<html>
<head>
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/db.js"></script>
<script type="text/javascript" src="js/oauthsimple.min.js"></script>
<script type="text/javascript" src="js/OpenDatabase.js"></script>
<script type="text/javascript">
var Popup = function(){
    if(chrome.experimental.extension.getPopupView()){
        return chrome.experimental.extension.getPopupView();
    }else{
        var v = chrome.extension.getViews(),p;
        for(var i in v){
            if(v[i] && v[i].LT){
                p = v[i];
            }
        }
        return p;
    }
}
var AuthMode = null;
var Database = new OpenDatabase('Chrowety');
var m = function(i){return Math.floor(i*60000)};
var s = function(i){return Math.floor(i*1000)};
var OAuth = {
    consumer:{
      key: 'eWGZ2e24PmM301P1i0f6bQ',
      secret: '4zwn3jgT4To5Hl6i4fPGkB3mBqkP3Sif5rTVKLPuqg'
    },
    token:{},
    tab:null,

    Sign:function(url, dados, method){
        var sig = {
            consumer_key: OAuth.consumer.key,
            shared_secret: OAuth.consumer.secret
        };
        if(OAuth.token.oauth_token){
            sig.oauth_token = OAuth.token.oauth_token;
            sig.oauth_secret = OAuth.token.oauth_token_secret;
        }
        //console.log(sig);
        return OAuthSimple().sign({
            path: url,
            action: method ? method : 'GET',
            parameters: dados ? dados : {},
            signatures:  sig
        });
    },

    RequestToken:function(out){
        var Tok = new Request(OAuth.Sign(api.request_token).signed_url , 'get', 'text');
        //var Tok = new Request(api.request_token, 'get', 'text');
            Tok.sucesso = function(e){
                var args = e.split("&");
                for(i in args) {
                  args[i] = args[i].split("=");
                  OAuth.token[args[i][0]] = args[i][1];
                }
                try{Popup().init()}
                catch(e){}
            }
            Tok.erro = function(e){
                OAuth.token.erro = true;
                try{Popup().init()}
                catch(e){}
            }
            Tok.init();
    },

    Autorisar:function(){
        var pag = api.autorize+'?oauth_token='+OAuth.token.oauth_token;
        chrome.tabs.create({
            url: pag,
            selected: true
        }, function(tab){
            OAuth.tab = tab.id;
        });
    },

    Access:function(){
        AuthMode = 'OAuth';
        var Acs = new Request(api.access_token, 'get', 'text');
            Acs.dados = {oauth_verifier: OAuth.pin};
            Acs.sucesso = function(e){
                var args = e.split("&");
                for(i in args) {
                  args[i] = args[i].split("=");
                  OAuth.token[args[i][0]] = args[i][1];
                }
                OAuthAutoLogin();
            };
            Acs.initOAuth();
    },

    ParseString:function(str){
        return OAuthSimple()._parseParameterString(str);
    },

    SalvaToken:function(){
        db.salva('token', J2S(OAuth.token));
    },
    LoadToken:function(){
        OAuth.token = S2J(db.pega('token'));
    },
    DeletaToken:function(callback){
        db.deleta('token');
        OAuth.token = {};

        if(callback){
            try{
              eval(callback);
            }catch(e){}
        }
    },

};

function Request(url, met, type, ctype){
        this.url = url;
        this.met = met;
        this.type = type ? type : "json";
        this.dados = {};
        this.sucesso = null;
        this.erro = null;
        this.contentType = ctype ? ctype : "application/x-www-form-urlencoded",

        this.initOAuth = function(){
            if(AuthMode == 'OAuth'){
                this.url = OAuth.Sign(this.url, this.dados, this.met).signed_url;
                this.dados = {};
            }
            this.init();
        }

        this.init = function(){
          $.ajax({
                url: this.url,
                type: this.met,
                data: this.dados,
                dataType: this.type,
                contentType: this.contentType,
                success: this.sucesso,
                error: this.erro,
                timeout: s(6)
             }
          );
        }
}
var tBase = 'https://api.twitter.com/1';
var tBaseOAuth = 'https://api.twitter.com';

var api = {
    access_token:                  tBaseOAuth+ '/oauth/access_token',
    request_token:                 tBaseOAuth+ '/oauth/request_token',
    autorize:                      tBaseOAuth+ '/oauth/authorize',

    login:function(){return        tBase+ '/account/verify_credentials.json'        },
    logout:function(){return       tBase+ '/account/end_session.json'               },
    rate:function(){return         tBase+ '/account/rate_limit_status.json'         },
    home:function(){return         tBase+ '/statuses/home_timeline.json'            },
    friends:function(){return      tBase+ '/statuses/friends_timeline.json'         },
    mentions:function(){return     tBase+ '/statuses/mentions.json'                 },
    messagesSent:function(){return tBase+ '/direct_messages/sent.json'              },
    messages:function(){return     tBase+ '/direct_messages.json'                   },
    favorites:function(){return    tBase+ '/favorites.json'                         },
    update:function(){return       tBase+ '/statuses/update.json'                   },
    updateDM:function(){return     tBase+ '/direct_messages/new.json'               },
    user_show:function(){return    tBase+ '/users/show.json'                        },
    retweet:function(id){return    tBase+ '/statuses/retweet/'+id+'.json'           },
    destroy:function(id){return    tBase+ '/statuses/destroy/'+id+'.json'           },
    destroyDM:function(id){return  tBase+ '/direct_messages/destroy/'+id+'.json'    },
    favorite:function(id){return   tBase+ '/favorites/create/'+id+'.json'           },
    unfavorite:function(id){return tBase+ '/favorites/destroy/'+id+'.json'          },
    follow:function(id){return     tBase+ '/friendships/create/'+id+'.json'         },
    unfollow:function(id){return   tBase+ '/friendships/destroy/'+id+'.json'        },	
    lists:function(user){return    tBase+ '/'+user+'/lists.json'                    },
    list:function(user,lid){return tBase+ '/'+user+'/lists/'+lid+'/statuses.json'   },

    googl:'http://goo.gl/api/url',
    urli: 'http://urli.nl/api.php',
    miudin: 'http://miud.in/api-create.php',
    threely:'http://3.ly/',
    twitpic:'http://twitpic.com/show/',
    twitgoo:'http://twitgoo.com/api/message/info/',
    tweetphoto_view:'http://TweetPhotoAPI.com/api/TPAPI.svc/imagefromurl',
    tweetphoto_post:'http://tweetphotoapi.com/api/tpapi.svc/upload2',
    migre_short:'http://migre.me/api.xml',
    migre_long:'http://migre.me/api_redirect2.xml',
    bitly_short:'http://api.bit.ly/shorten',
    jmp_short:'http://api.j.mp/shorten',
    isgd:'http://is.gd/api.php',
    trim:'http://api.tr.im/v1/trim_simple',
    untrim:'http://untr.im/api/ajax/api',

    audio:'http://vjnrv.net/Labs/Chrowety/Res/alerta.wav'
};
var time = {};

var Logado=false,_iniciou,total=0,new_count=0,api_limit = null,api_checked=false,aid,oid,taid;
var AlertaAudioFile = new Audio();
function SinceDate(TD){
    var a = new Date(TD);
    return a.getDate()+'/'+(a.getMonth()+1)+'/'+a.getFullYear();
}

function ApiDate(TD){
    var a = new Date(TD);
    return a.getHours()+':'+a.getMinutes()+':'+a.getSeconds();
}

function TweetData(TD) {
    var TD = new Date(TD);
        //console.log(TD.toUTCString());
    var AD = new Date();
        //console.log(AD.toUTCString());
        /*
    var Tweet = {
        ano: TD.getUTCFullYear(),
        mes: TD.getUTCMonth(),
        dia: TD.getUTCDay(),
        hor: TD.getUTCHours(),
        min: TD.getUTCMinutes(),
        sec: TD.getUTCSeconds()
    };
    var Atual = {
        ano: AD.getUTCFullYear(),
        mes: AD.getUTCMonth(),
        dia: AD.getUTCDay(),
        hor: AD.getUTCHours(),
        min: AD.getUTCMinutes(),
        sec: AD.getUTCSeconds()
    };

    console.log(Tweet);
    console.log(Atual);
    var offset = TD.getTimezoneOffset() / 60;
    */
    var TD_ = Date.parse(TD); //Date.parse(TD.toUTCString());
    var s;
    //var Calc = (new Date(new Date().toUTCString()).getTime() - TD_) / 1000;
    var Calc = (new Date().getTime() - TD_) / 1000;
    if(Calc < 15) {
            return Traduz('just_now');
    }
    else if(Calc < 60) {
            return Traduz('less_than_a_minute_ago');
    }
    else if(Calc < 60 * 60) {
            var Min = parseInt(Calc / 60);
  		    s = (Min > 1) ? Traduz('minutes_ago', [Min]) : Traduz('a_minute_ago');
            return s;
    }
    else if(Calc < 60 * 60 * 24) {
            var Hor = parseInt(Calc / (60 * 60));
  		    s = (Hor > 1) ? Traduz('hours_ago', [Hor]) : Traduz('a_hour_ago');
            return s;
    }
    else if(Calc < 60 * 60 * 24 * 30) {
            var Day = parseInt(Calc / (60 * 60 * 24));
  		    s = (Day > 1) ? Traduz('days_ago', [Day]) : Traduz('a_day_ago');
            return s;
    }
    else if(Calc < 60 * 60 * 24 * 30 * 12) {
            var Month = parseInt(Calc / (60 * 60 * 24 * 30));
  		    s = (Month > 1) ? Traduz('months_ago', [Month]) : Traduz('a_month_ago');
            return s;
    }
    else {
            return Traduz('years_ago');
    }
}

var tws = {
    home:{
      total:0,
      last:0,
      new_count:0,
      tweets:[],
      tw:[]
    },
    mentions:{
      total:0,
      last:0,
      new_count:0,
      tweets:[],
      tw:[]
    },
    messages:{
      total:0,
      last:0,
      new_count:0,
      tweets:[],
      tw:[]
    },
    favorites:{
      total:0,
      last:0,
      new_count:0,
      tweets:[],
      tw:[]
    },
    lists:{
      loaded:false,
      total:0,
      full_names:[],
      names:[],
      lists:[],
      ativos:[]
    },
    list:[],
};
function Traduz(s, e, pl){
    var re = chrome.i18n.getMessage(s, e);

    if(re){
        return re;
    }else{
        return s;
    }
}

function LoadIcon(){
	var ico;
	if(config.icone == 'chrome'){
		ico = 'x19_chrome';
	}else if(config.icone == 'chrome2'){
        ico = 'x19_chrome2';
	}else{
		ico = 'x19';
	}
	var pat = 'icones/'+ico+'.png';
	chrome.browserAction.setIcon({path:pat});	
}

function LoadConfig(){
    if(!db.pega('version'))
    {
        db.deleta('config');
        db.salva('version', Chrowety.version());
    }
    else if(db.pega('version') != Chrowety.version())
    {
        try{
          if(db.pega('AuthMode') != "API"){
            db.deleta('z_z');
          }
        }catch(e){console.log(e)}
        //db.deleta('config');
        db.salva('version', Chrowety.version());
    }

    if(db.pega('config') && db.pega('config') != null && typeof S2J(db.pega('config')) == "object")
    {
        console.log('LoadConfig() > Definida');
        config = S2J(db.pega('config'));
        if(!config.base_api){
            config.base_api = DefaultConfig.base_api;
        }
        if(!config.translate_tweets_to){
            config.translate_tweets_to = DefaultConfig.translate_tweets_to;
        }
        if(!config.refresh.list){
            config.refresh.list = 5;
        }
        if(!config.icone){
            config.icone = 'normal';
        }
		if(!config.popup_height){
			config.popup_height = '450px';			
		}
		if(!config.show_username){
			config.show_username = "false";
		}
		if(!config.desktop_notifications){
			config.desktop_notifications = "true";
		}
		if(!config.desktop_notifications_timeout){
			config.desktop_notifications_timeout = 10;
		}
		if(!config.audio_alerta){
			config.audio_alerta = "true";
		}
		if(!config.bitly_key){
			config.bitly_key = "R_9feba944d032e9857730684feb87e1be";
		}
		if(!config.bitly_user){
			config.bitly_user = "chrowety";
		}
		if(!config.Geo){
            config.Geo = {
                enabled: "false",
                Location: [],
                Address: null
            };
		}
        db.salva('config', J2S(config));
        //console.log(config);
    }else
    {
        console.log('LoadConfig() > Padrão');
        config = DefaultConfig;
    }

    tBase = config.base_api;
	LoadIcon();
}

function ReLoadConfig(){

    var _NAME_ = new Array('home', 'mentions', 'messages', 'favorites');
    for(n in  _NAME_){
      try{
        window.clearInterval(time[_NAME_[n]]);
      }catch(e){console.log(e)}
    }
    LoadConfig();
    for(n in  _NAME_){
      try{
        console.log('ReLoadConfig() > '+_NAME_[n]);
        time[_NAME_[n]] = setInterval('Chrowety.'+_NAME_[n]+'.Since()', m(config.refresh[_NAME_[n]]));
      }catch(e){console.log(e)}
    }
}

var config = {};
var DefaultConfig = {
    language: 'en',
    base_api: 'https://api.twitter.com/1',
    translate_tweets_to: 'en',
    url_shortener: 'goo.gl',
    tweet_font_size: '9pt',
    tweet_shadow: "false",
    twitter_question: false,
    link_in_bg: "false",
	icone: 'normal',
	popup_height: '450px',
	show_username: "true",
    desktop_notifications: 'true',
    desktop_notifications_timeout: 10,
    alerts: "false",
    audio_alerta: "true",
    alerts_max:5,
    bitly_key: 'R_9feba944d032e9857730684feb87e1be',
    bitly_user: 'chrowety',
    Geo:{
        enabled: "false",
        Location: [],
        Address: null,
    },
    start_count:{
      home:10,
      mentions:10,
      messages:20,
      favorites:20,
    },
    old_count:{
      home:10,
      mentions:10,
      messages:10,
      favorites:20,
    },
    refresh:{
      home:3,
      mentions:5,
      messages:7,
      favorites:60,
      limit_check:3,
      profile:60,
      list:5,
    }
};

function J2S(obj){
    return JSON.stringify(obj);
}

function S2J(str){
    return JSON.parse(str);
}


function Sortear(ob, campo, reverso){
    var ob2 = ob;
    var SortFunc = function(field, reverse, primer){

       reverse = (reverse) ? -1 : 1;

       return function(a,b){

           a = a[field];
           b = b[field];

           if (typeof(primer) != 'undefined'){
               a = primer(a);
               b = primer(b);
           }

           if (a<b) return reverse * -1;
           if (a>b) return reverse * 1;
           return 0;

       }
    };

    return ob2.sort(SortFunc(campo, reverso, parseInt));
}

function SaveCache(){
    var user     = db.pega('user');
    var _NAME_ = new Array('home', 'mentions', 'messages', 'favorites');
    for(n in  _NAME_){
      try{
        tws[_NAME_[n]].ultimo         = Chrowety[_NAME_[n]].ultimo
        tws[_NAME_[n]].primeiro       = Chrowety[_NAME_[n]].primeiro
        tws[_NAME_[n]].primeiro_lista = Chrowety[_NAME_[n]].primeiro_lista
        tws[_NAME_[n]].mostrando      = Chrowety[_NAME_[n]].mostrando
      }catch(e){console.log(e)}
    }
    var _tws     = J2S(tws);
    console.log(tws)
    db.salva(user+'_TwCache', true);
    db.salva(user+'_tws', _tws);
}

function CalculaApiRequests(){
    var a = config.refresh,li=0;
	for(i in tws.list){
		if(tws.list[i] && tws.list[i]._loaded) li++;
	}
	var list = (60/a.list) * li;
    var calc = (60/a.home) + (60/a.mentions) + (60/a.messages) + (60/a.favorites) + list;
    calc = ((calc) + 4).toFixed();
    perc = ((calc / 150) * 100).toFixed();
    return {numero: calc, porcento: perc};
}
var RateTrava = null;
function RateLimit(func){
    console.log('RateLimit()');
    if(RateTrava){
        return false;
    }
    RateTrava = true;
    var Rate = new Request(api.rate(), 'get');
        Rate.sucesso = function(json){
            if(json && json.remaining_hits){
                api_limit = json.remaining_hits;
                db.salva('api_limit', json.remaining_hits);
                db.salva('api_reset_time', json.reset_time);
                if(api_limit > 0){
                    api_checked = true;
                    console.log('RateLimit() > OK > '+api_limit+' | '+ ApiDate(db.pega('api_reset_time')));
                    if(func){
                      try{eval(func)}catch(e){}
                    }
                }else{
                    console.log('RateLimit() > Limit Exceeded');
                    try{
                      Popup().RefreshLimit(new_count);
                    }catch(e){}
                }
            }else{
                Rate.erro();
            }
            RateTrava = null;
        }

        Rate.erro = function(e){
            console.log('RateLimit() > FAIL');
            RateTrava = null;
            setTimeout('RateLimit(\''+func+'\')', s(10));
        }

        Rate.initOAuth();
}

function CheckLimit(r){
    RateLimit(r);
}

function ClearUnreads(tm){
    //console.log('Cleaning Unreads > '+tm);

    if(tws.lists && tws.list && tws.list[tm]){
        tws.list[tm].new_count = 0;
        for(id in tws.list[tm].tweets){
            tws.list[tm].tweets[id].read = true;
        }
    }else{
        tws[tm].new_count = 0;
        for(id in tws[tm].tweets){
            tws[tm].tweets[id].read = true;
        }
    }

    MostraCount();
}

function SalvaProfile(json){
  db.salva('id', json.id);
  db.salva('user', json.screen_name);
  db.salva('nome', json.name);
  db.salva('foto', json.profile_image_url);
  db.salva('info', json.description);
  db.salva('local', json.location);
  db.salva('seguidores', json.followers_count);
  db.salva('seguindo', json.friends_count);
  db.salva('favoritos', json.favourites_count);
  db.salva('profile_loaded', true);
}

function SalvaListas(){
    var listas = tws.list;
    var temp = [],n=0;
    for(var i in listas){
        if(listas[i].ativo){
            temp[n] = i;
            n++;
        }
        else{
            continue
        }
    }
    tws.lists.ativos = temp;
    db.salva( db.pega('user') + '_listas_names' , J2S(tws.lists));
    return temp;
}

function LoadListas(){
    time.list = [];
    if(db.pega((db.pega('user')+'_listas'))){
        db.deleta(db.pega('user')+'_listas');
    }
    var listas_n = S2J(db.pega( (db.pega('user') + '_listas_names') ));
    if(listas_n && typeof(listas_n) == 'object'){
        tws.lists = listas_n;
        for(var i in tws.lists.ativos){
            i = tws.lists.ativos[i];
            console.log('List: '+i);
            if(!tws.list[i]){
                tws.list[i] = {};
                tws.list[i].total = 0;
                tws.list[i].tweets = [];
                Chrowety.List.Run(i, 'LT.initLists()');
            }
        }
    }else{
        tws.lists = {
            loaded:false,
            total:0,
            full_names:[],
            names:[],
            lists:[],
            ativos:[]
        }
    }
}

function ContaTweets(tm, list){
    var i=0;
    var id=null,fid=null,fit=null;
    if(list){
        var tw = Sortear(tws[tm][list].tweets, 'id', false);
    }else{
        var tw = Sortear(tws[tm].tweets, 'id', false);
    }
    for(a in tw){
      i++;
      id = tw[a].id;
      if(list){
          if(i == 1){tws[tm][list].primeiro_lista = id;fid=id}
          tws[tm][list].ultimo = id;
      }else{
          if(i == 1){Chrowety[tm].primeiro_lista = id;fid=id}
          if(!tw[a].own){Chrowety[tm].ultimo = id}
      }
    }
    if(list){
        tws[tm][list].total = i;
    }else{
        tws[tm].total = i;
    }
    //primeiro = id;
    //console.log('ContaTweet() '+tm+': '+i+' LastID: '+id+' FirstID: '+fid+' First_In: '+Chrowety[tm].primeiro_lista);
}

function MostraCount(){
    var Total = tws.home.new_count + tws.mentions.new_count + tws.messages.new_count;
    if(Total == 0){
        Total = '';
    }
    chrome.browserAction.setBadgeText({text:''+Total});

    return Total > 0 ? Total : 0;
}

var fec = {
    ByTid:function(tm, tid, del, list){
        if(list){
            var a = tws[tm][list].tweets;
        }else{
            var a = tws[tm].tweets;
        }
        for(i in a){
            if(a[i] && a[i].id == tid){
                if(del){
                  //delete tws[tm].tweets[i];
                  delete a[i];
                  return false;
                }
                return a[i];
                break;
            }else if(a[i].retweeted_status && a[i].retweeted_status.id == tid){
                if(del){
                  //delete tws[tm].tweets[i];
                  delete a[i];
                  return false;
                }
                return a[i];
                break;
            }
        }
    },

    clearNull:function(ob, n){
        if(ob && typeof(ob) == 'object'){
            var temp = [], i=0;
            for(i in ob){
                //if(ob[i] != 'undefined' && ob[i] != null){
                if(n == i) break;
                if(ob[i] && ob[i].id){
                    temp[temp.length] = ob[i];
                }else{
                    continue;
                }
                i++;
            }
            return temp;
        }else{
            return false;
        }
    },

    refresh:function(tm){
        var ob = tws[tm].tweets;
        for(id in ob){
            ob[id].html = Layout(ob[id], tm);
        }
    },

    ref:function(i, tm, list){
        if(list){
            var ob = tws.list[tm].tweets[i];
        }else{
            var ob = tws[tm].tweets[i];
        }
            if(tm == 'messages'){
                ob.html = LayoutMessage(ob, tm);
            }else{
                if(list){
                    ob.html = Layout(ob, tm, true);
                }else{
                    ob.html = Layout(ob, tm);
                }
            }
        return ob.html;
    },

    last:function(tm, n, max){
        var re = '';
        for(i=0;i<n;i++){
            if(i>=max)break;
            re += LayoutPage(Sortear(tws[tm].tweets, 'id', true)[i], tm);
        }
        return re;
    },

    lastNotifications:function(tm, n, max){
        var re = [];
        for(i=0;i<n;i++){
            if(i>=max)break;
            re[i] = LayoutNotifications(Sortear(tws[tm].tweets, 'id', true)[i], tm);
        }
        return re;
    },

    html:function(tm, cf, count, list){
        //console.log('fec('+tm+', '+cf+', '+count+', '+list+')');
        var i = 0;
        var re='';
        var ob = [];
        var total = 0;
        if(list){
            if(typeof(tws.list[tm]) == 'object'){
                ob = Sortear(tws.list[tm].tweets, 'id', true);
                total = count ? count : 20;
            }
        }else{
            if(typeof(tws[tm].tweets) == 'object'){
                ob = Sortear(tws[tm].tweets, 'id', true);
                total = count ? count : config.start_count[tm];
            }
        }
        var ia = 0;
        for(id in ob){
          if(!ob[id]){
                continue;
          }
          if(cf && cf.max){
            //console.log('fec.html() > max: '+cf.max+ ' e: '+ob[id].id);
            if(i > total)break;
            if(ob[id].id == ia)continue;
            if(ob[id].id < cf.max){
              re = re+fec.ref(id, tm, list);
              ia = ob[id].id;
              if(list){
                tws.list[tm].primeiro_lista = tws.list[tm].primeiro =  ia;
              }else{
                Chrowety[tm].primeiro_lista = Chrowety[tm].primeiro =  ia;
              }
              i++;
            }
          }
          else if(cf && cf.since){
            //console.log('fec.html() > since: '+cf.since+ ' e: '+ob[id].id);
            if(i > total)break;
            if(ob[id].id == ia)continue;
            if(ob[id].id > cf.since){
              re = re+fec.ref(id, tm, list);
              ia = ob[id].id;
              if(list){
                tws.list[tm].primeiro_lista = tws.list[tm].primeiro =  ia;
              }else{
                Chrowety[tm].primeiro_lista = Chrowety[tm].primeiro =  ia;
              }
              i++;
            }
          }else{
            if(i > total)break;
            if(ob[id].id == ia)continue;
            re = re+fec.ref(id, tm, list);
            ia = ob[id].id;
              if(list){
                tws.list[tm].primeiro_lista = tws.list[tm].primeiro =  ia;
              }else{
                Chrowety[tm].primeiro_lista = Chrowety[tm].primeiro =  ia;
              }
            i++;
          }

        }
        if(list){
          tws.list[tm].mostrando += i;
        }else{
          Chrowety[tm].mostrando += i;
        }

        //ContaTweets(tm);
        return re;
    }
}

/* CHROWETY CONTROLLER */
var Chrowety = {

    profile_last_view: null, // nome do usuario sendo visualizado

    version:function(){
          var version = 'NaN';
          var xhr = new XMLHttpRequest();
          xhr.open('GET', chrome.extension.getURL('manifest.json'), false);
          xhr.onreadystatechange = function() {
            if (this.readyState == 4) {
              var manifest = JSON.parse(this.responseText);
              version = manifest.version;
            }
          };
          xhr.send();
          return version;
    },


    Run:function(){
        console.log('Chrowety.Run()');
        var guia = db.pega('AbaAtiva');
        try{
            Popup().init();
        }catch(e){}
        Chrowety.home.Run('LT.home()');
        Chrowety.mentions.Run('LT.CheckLoadeds()');
        Chrowety.messages.Run('LT.CheckLoadeds()');
        Chrowety.messages.Run('LT.CheckLoadeds()', true);
        Chrowety.favorites.Run('LT.CheckLoadeds()');
        LoadListas();
        time.profile = window.setInterval('Chrowety.profile()', m(config.refresh.profile));
        time.limit = window.setInterval('CheckLimit()', m(config.refresh.limit_check));
    },

    login:function(lembra, login){
      var Login = new Request(api.login(), 'get');
          Login.sucesso = function(json){
              if(AuthMode == "OAuth"){
                  console.log('Chrowety.login() '+AuthMode);
                  db.salva('profile_view', J2S({}));
                  db.salva('logado', true);
                  db.salva('AuthMode', 'OAuth');
                  db.salva('version', Chrowety.version());
                  OAuth.SalvaToken();
                  SalvaProfile(json);
                  CheckLimit('Chrowety.Run()');
              }else{
                  console.log('Chrowety.login() '+AuthMode);
                  db.salva('z_z', login);
                  console.log('Logado...');
                  Logado = true;
                  AuthMode = 'API';
                  db.salva('logado', lembra);
                  db.salva('AuthMode', 'API');
                  db.salva('profile_view', J2S({}));
                  db.salva('version', Chrowety.version());
                  SalvaProfile(json);
                  CheckLimit('Chrowety.Run()');
                  Popup().LoginStatus(Traduz('sucess_login'));
                  Popup().init();
                  console.log('Chrowety.login() > OK');
              }

              chrome.browserAction.setTitle({title:'Chrowety ('+db.pega('user')+')'});

              try{
                Popup().LoadProfile();
              }catch(e){}

          };
          Login.erro = function(){
              if(AuthMode == "OAuth"){
                    Chrowety.login();
              }else{
                Popup().LoginStatus(Traduz('login_failed', '...'));
                console.log('Chrowety.login() > FAIL');
              }
          };
          Login.initOAuth();
    },

    logout:function(lembra){
      Chrowety.Clean();
      chrome.browserAction.setBadgeText({text:''});
      console.log('Chrowety.logout()');
      var bak_conf = db.pega('config');
      var bak_users = db.pega('profile_view');
      db.limpa();
      window.clearInterval(time.limit);
      window.clearInterval(time.home);
      window.clearInterval(time.metions);
      window.clearInterval(time.messages);
      window.clearInterval(time.favorites);
      window.clearInterval(time.profile);
      if(bak_conf != null){
        db.salva('config', bak_conf);
      }
      db.salva('profile_view', bak_users);
      Logado = false;
      if(AuthMode == "OAuth"){
        OAuth.DeletaToken('OAuth.RequestToken(true)');
      }else{
        jQuery.ajaxSetup({'beforeSend': function(xhr){xhr.setRequestHeader("Authorization", "Basic "+db.pega('z_z'))}});
        var Logout = new Request(api.logout(), 'post');
            Logout.sucesso = function(){
              console.log('Chrowety.logout() > OK');
            };
            Logout.erro = function(){
                  console.log('Chrowety.logout() > FAIL');
            };
            Logout.initOAuth();
      }
      AuthMode = null;
    },

    // Atualiza informa��es do perfil
    profile:function(){
      console.log('Chrowety.profile()');
      var Profile = new Request(api.login(), 'get');
          Profile.sucesso = function(json){
            console.log('Chrowety.profile() > OK');
            SalvaProfile(json);
          };
          Profile.erro = function(){
            console.log('Chrowety.profile() > FAIL');
          };
          Profile.initOAuth();
    },

    user:function(uname){
      var U = S2J(db.pega('profile_view'));
      if(U && U[uname]){
        console.log('Cache do Usuario encontrado');
        Popup().ShowUserOK(U[uname]);
        return false;
      }

      console.log('Usuario sem Cache');

      var User = new Request(api.user_show(), 'get');
          User.dados = {screen_name: uname};
          User.sucesso = function(json){
            console.log('Chrowety.user() > OK');
            var U = S2J(db.pega('profile_view'));
            U[uname] = json;
            db.salva('profile_view', J2S(U));
            Popup().ShowUserOK(json);
          };
          User.erro = function(){
            console.log('Chrowety.user() > FAIL');
            Popup().ShowUserERRO();
          };
          User.initOAuth();
    },

    /*
     * @s String - texto do tweet
     * @reply_id Number - id do tweet de resposta
     * @tm String - Timeline do tweet
     */
    update:function(s, reply_tid, tm, callback, rt){
      var src = 'chrowety';
      var Up = new Request(api.update(), 'post');
          if(config.Geo.enabled == 'true'){
              var _ll = config.Geo.Location;
              Up.dados = reply_tid && !rt ? {lat: _ll[0], long: _ll[1], status: s, in_reply_to_status_id: reply_tid, source: src} : {lat: _ll[0], long: _ll[1], status: s, source: src};
          }else{
              Up.dados = reply_tid && !rt ? {status: s, in_reply_to_status_id: reply_tid, source: src} : {status: s, source: src};
          }
          Up.sucesso = function(w){
            console.log('Chrowety.update() > OK');
            ht = Layout(w, tm);
            w.own = true;
            tws.home.total++;
            tws.home.tweets[tws.home.total] = w;
            tws.home.tweets[tws.home.total].read = true;
            Utils.Tweet.DetectSaveMention(w, 'home');
                if(!callback){
                    if(reply_tid){
                        Popup().ReplyOK(reply_tid, tm);
                    }else{
                        Popup().UpdateOK(ht, tm);
                    }
                }else{
                    callback(true);
                }

          }
          Up.erro = function(){
                console.log('Chrowety.update() > FAIL');
                if(!callback){
                    if(reply_tid){
                        Popup().ReplyFAIL(reply_tid, tm, "error");
                    }else{
                        Popup().UpdateFAIL(reply_tid, tm, "error");
                    }
                }
                else{
                    callback();
                }
          }
          Up.initOAuth();
    },

    updateDM:function(s, user, tid, tm){
      var _NAME_ = 'messages';
      var Up = new Request(api.updateDM(), 'post');
          Up.dados = {screen_name: user, text: s};
          Up.sucesso = function(w){
            console.log('Message send: '+s);

            tws[_NAME_].total++;
            tws[_NAME_].tweets[tws[_NAME_].total] = w;
            tws[_NAME_].tweets[tws[_NAME_].total].read = true;

            Chrowety[_NAME_].ultimo = w.id;

            Popup().ReplyDMOK(tid, (tm ? tm : _NAME_));
            console.log('Chrowety.updateDM() > OK');
          }
          Up.erro = function(e){
                console.log('Chrowety.updateDM() > FAIL');
                var status = e.statusText;
                if(status == "Forbidden"){
                    Popup().ReplyDMFAIL(tid, tm, "forbidden");
                    console.log("You cannot send a direct message to "+user+" because they are not following you.");
                }else{
                    Popup().ReplyDMFAIL(tid, tm, "error");
                }
          }
          Up.initOAuth();
    },


    deleta:function(tid, time, rt){
      var del = new Request(api.destroy(tid), 'post');
          del.sucesso = function(){
            fec.ByTid(time, tid, true);
            var _NAME_ = new Array('home', 'mentions');
            for(n in  _NAME_){
              try{
                fec.ByTid(_NAME_[n], tid, true);
              }catch(e){console.log(e)}
            }
            if(rt){
                Popup().UndoRTOK(tid, time, rt);
                fec.ByTid(time, rt).retweeted_by_me = false;
                fec.ByTid(time, rt).retweeted_by_me_status = null;
            }else{
                Popup().DeletaOK(tid, time);
            }
            console.log('Chrowety.deleta() > OK');
          }
          del.erro = function(){
                console.log('Chrowety.deleta() > FAIL');
            if(rt){
                Popup().UndoRTFAIL(tid, time, rt);
            }else{
                Popup().DeletaFAIL(tid, time);
            }
          }
          del.initOAuth();
    },

    deletaDM:function(tid, time){
      var del = new Request(api.destroyDM(tid), 'post');
          del.sucesso = function(){
                fec.ByTid(time, tid, true);
                Popup().DeletaOK(tid, time);
                console.log('Chrowety.deletaDM() > OK');
          }
          del.erro = function(){
                Popup().DeletaFAIL(tid, time);
                console.log('Chrowety.deletaDM() > FAIL');
          }
          del.initOAuth();
    },

    retweet:function(tid, time){
      var rt = new Request(api.retweet(tid), 'post');
          rt.sucesso = function(w){
            console.log('Retweeted: '+tid);
            /*
            w.own = true;
            tws.home.total++;
            tws.home.tweets[tws.home.total] = w;
            tws.home.tweets[tws.home.total].read = true;
            */
            fec.ByTid(time, tid).retweeted_by_me = true;
            fec.ByTid(time, tid).retweeted_by_me_status = w.id;
            Popup().RetweetOK(tid, time, w.id);
          }
          rt.erro = function(e){
            var status = 'error';
            try{
                status = e && e.statusText ?  e.statusText : status;
            }catch(e){}
            if(status == "Forbidden"){
                Popup().RetweetFAIL(tid, time, "forbidden");
            }else{
                Popup().RetweetFAIL(tid, time, "error");
            }
            console.log('Chrowety.retweet() > FAIL');
          }
          rt.initOAuth();
    },

    fav_active:false,
    favorite:function(tid, time, list){
      console.log('favorite: '+tid+' - '+time);
      Chrowety.fav_active = true;
      var fav = new Request(api.favorite(tid), 'post');
          fav.sucesso = function(){
            console.log('Favoriting tweet: '+tid);
            //(tm, tid, del, list)
            fec.ByTid(time, tid, null, list).favorited = true;
            //fec.ByTid(time, tid).favorited = true;
            try{
              tws['favorites'].total++;
              tws['favorites'].tweets[tws['favorites'].total] = fec.ByTid(time, tid, null, list);
            }catch(e){}
            Popup().FavOK(tid, true, time);
            Chrowety.fav_active = false;
          }
          fav.erro = function(){
                console.log('Chrowety.favorite() > FAIL');
          }
          fav.initOAuth();
    },

    unfav_active:false,
    unfavorite:function(tid, time, list){
      Chrowety.unfav_active = true;
      var fav = new Request(api.unfavorite(tid), 'post');
          fav.sucesso = function(){
            console.log('Unfavoriting tweet: '+tid);
            fec.ByTid(time, tid, null, list).favorited = false;
            try{
                fec.ByTid('favorites', tid, true);
                fec.ByTid('home', tid).favorited = false;
                fec.ByTid('mentions', tid).favorited = false;
            }catch(e){}
            Popup().FavOK(tid, false, time);
            Chrowety.unfav_active = false;
          }
          fav.erro = function(){
                console.log('Chrowety.unfavorite() > FAIL');
          }
          fav.initOAuth();
    },

    Clean:function(){
        var _NAME_ = new Array('home', 'mentions', 'messages', 'favorites');
        for(n in  _NAME_){
          try{
            console.log('Chrowety.Clean() > '+_NAME_[n]);
            Chrowety[_NAME_[n]]._loaded = false;
            Chrowety[_NAME_[n]].ultimo = null;
            Chrowety[_NAME_[n]].primeiro = null;
            Chrowety[_NAME_[n]].primeiro_lista = null;
            Chrowety[_NAME_[n]].scroll = 0;
            Chrowety[_NAME_[n]].pagina = null;
          }catch(e){console.log(e)}
        }
        db.deleta('AbaAtiva');
        tws = null;
        tws = {home:{total:0,last:0,new_count:0,tweets:[]},mentions:{total:0,last:0,new_count:0,tweets:[]},messages:{total:0,last:0,new_count:0,tweets:[]},favorites:{total:0,last:0,new_count:0,tweets:[]}};
    },


    Lists:function(callback){
        var _NAME_ = 'lists';
        var User   = db.pega('user');
        var Lists = new Request(api[_NAME_](User), 'get');
            Lists.sucesso = function(json,s){
               if(typeof tws[_NAME_] != 'object'){
                    tws[_NAME_] = [];
               }
               tws[_NAME_].names = [];
               tws[_NAME_].full_names = [];
               tws[_NAME_].total = 0;
               $.each(json.lists,function(n,w){
                   tws[_NAME_].names[tws[_NAME_].total] = w.slug;
                   tws[_NAME_].full_names[tws[_NAME_].total] = w.full_name;
                   tws[_NAME_].lists[tws[_NAME_].total] = w;
                   if(typeof tws.list != 'object'){
                      tws.list = [];
                   }
                   if(!tws.list[w.slug]){
                       tws.list[w.slug] = {};
                       tws.list[w.slug].total = 0;
                       tws.list[w.slug].tweets = [];
                   }
                   tws[_NAME_].total++;
               });
               time.list = [];
               tws.lists.loaded = true;
               SalvaListas();
               if(callback){
                    try{eval('Popup().'+callback)}catch(e){}
               }else{
                    try{
                         Popup().LT.Lists(tws[_NAME_].names);
                    }catch(e){}
               }
            }
            Lists.erro = function(re){

            }
            Lists.initOAuth();
    },

    List: {

        Run: function(lid, callback){
            var _NAME_ = 'list';
            var User   = db.pega('user');
            var List = new Request(api[_NAME_](User,lid), 'get');
                List.dados = {per_page: 10, page: 1};
                List.sucesso = function(json,s){
                        if(!tws.list[lid]){
                           tws.list[lid] = {};
                           tws.list[lid].total = 0;
                           tws.list[lid].tweets = [];
                        }
                        var id;
                        $.each(json,function(n,w){
                          taid = w.id;
                          id = w.retweeted_status ? w.retweeted_status.id : w.id;
                          aid = id;
                          tws.list[lid].total++;
                          tws.list[lid].tweets[tws.list[lid].total] = w;
                          tws.list[lid].tweets[tws.list[lid].total].read = true;
                          ht = Layout(tws.list[lid].tweets[tws.list[lid].total], _NAME_);
                          //> Salva o perfil
                          var U = S2J(db.pega('profile_view'));
                          if(!U[w.user.screen_name]){
                              var ts = J2S(w.user);
                              ts = S2J(ts);
                              ts.status = J2S(w);
                              ts.status = S2J(ts.status);
                              delete ts.status.user;
                              U[ts.screen_name] = ts;
                              db.salva('profile_view', J2S(U));
                          }
                          //
                          if(n == 0){tws.list[lid].primeiro_lista = taid}
                        });
                        tws.list[lid]._loaded = true;
                        tws.list[lid].ultimo  = taid;
                        tws.list[lid].ativo   = true;
                        tws.list[lid].tweets = fec.clearNull(tws.list[lid].tweets);
                        tws.lists.ativos[tws.lists.ativos.length] = lid;
                        SalvaListas();
                        time[_NAME_][lid] = setInterval('Chrowety.List.Since(\''+lid+'\')', m(config.refresh[_NAME_]));
                        if(callback){
                          try{eval('Popup().'+callback)}catch(e){}
                        }
                }
                List.erro = function(re){
                    console.log('Chrowety.List.Run('+lid+') > FAIL'); 
                    window.setTimeout('Chrowety.'+_NAME_+'.Run(\''+lid+'\', \''+callback+'\')', m(1));
                }
                List.initOAuth();
        },

        Since:function(lid, since){ // Rate Limited
            var _NAME_ = 'list';
            if(!api_limit){return false}
            clearInterval(time[_NAME_][lid]);
            console.log('Chrowety.List.Since('+lid+')');
            ContaTweets(_NAME_, lid);
            var last = since ? since : tws.list[lid].ultimo;
            var novs = 0;
            var User   = db.pega('user');
            var Since = new Request(api[_NAME_](User,lid), 'get');
                Since.dados = {since_id: last};
                Since.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                n++;
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws.list[lid].total++;
                                tws.list[lid].tweets[tws.list[lid].total] = w;
                                tws.list[lid].tweets[tws.list[lid].total].read = false;
                                ht = Layout(tws.list[lid].tweets[tws.list[lid].total], _NAME_);
                                //> Salva o perfil
                                var U = S2J(db.pega('profile_view'));
                                if(!U[w.user.screen_name]){
                                    var ts = J2S(w.user);
                                    ts = S2J(ts);
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                    U[ts.screen_name] = ts;
                                    db.salva('profile_view', J2S(U));
                                }
                                //
                                novs = n;
                              });
                              time[_NAME_][lid] = setInterval('Chrowety.List.Since(\''+lid+'\')', m(config.refresh[_NAME_]));
                              tws.list[lid].ultimo = taid;
                              console.log('Chrowety.List.Since('+lid+') > New '+novs+' tweets');
                              //tws.list[lid].Notify(novs);
                              SalvaListas();
                }
                Since.erro = function(){
                    console.log('Chrowety.List.Since('+lid+') > FAIL');
                    window.setTimeout('Chrowety.'+_NAME_+'.Since(\''+lid+'\', \''+since+'\')', m(config.refresh[_NAME_]));
                }
                Since.initOAuth();
        },

        Max:function(lid, max){ // Rate Limited
            var _NAME_ = 'list';
            console.log('Chrowety.Lists.Max("'+lid+'")');
            if(!api_limit){return false}
            ContaTweets(_NAME_, lid);
            var first = max ? max : tws.list[lid].primeiro;
            var re = '';
            re = fec.html(lid, {max:first}, null, true);
            console.log('fec.html("'+lid+'")');
            if(!re){
              var User   = db.pega('user');
              var Max = new Request(api[_NAME_](User,lid), 'get');
                  Max.dados = {count: 10, max_id: first};
                  Max.sucesso = function(json,s){
                                var id;
                                $.each(json,function(n,w){
                                  if(n == 0){return;}
                                  taid = w.id;
                                  id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                  oid = id;
                                  ht = Layout(w, _NAME_, 'read');
                                  re = re+ht;
                                  tws.list[lid].total++;
                                  tws.list[lid].tweets[tws.list[lid].total] = w;
                                  //tws.list[lid].tweets[tws.list[lid].total].html = ht;
                                  var U = S2J(db.pega('profile_view'));
                                  var ts = J2S(w.user);
                                      ts = S2J(ts); // POG pra tirar relacionamento
                                      ts.status = J2S(w);
                                      ts.status = S2J(ts.status);
                                      delete ts.status.user;
                                  U[ts.screen_name] = ts;
                                  db.salva('profile_view', J2S(U));
                                });
                                tws.list[lid].primeiro = taid;
                                try{
                                  Popup().ShowMoreOK(re, _NAME_, lid);
                                }catch(e){}
                                //eval('Popup().'+callback);
                                console.log('Chrowety.List.Max('+lid+') > Pegou do Online');
                }
                Max.erro = function(){
                    console.log('Chrowety.List.Max('+lid+') > FAIL');
                }
                Max.initOAuth();
            }else{
                console.log('Chrowety.List.Max('+lid+') > Pegou do Cache');
                Popup().ShowMoreOK(re, _NAME_, lid);
            }
        },
   },

    home: {
        NAME: 'home',
        _loaded:false,
        scroll:0,
        mostrando:0,
        ultimo:null,
        primeiro:null,
        primeiro_lista:null,
        RunTrava: null,
        SinceTrava: null,

        Notify:function(n){
            var _NAME_ = 'home';
            tws[_NAME_].new_count += n;
            try{Popup().LT.HideLoad()}catch(e){}
            if(tws[_NAME_].new_count > 0){
                var c = tws[_NAME_].new_count;
                MostraCount();
                if(n){
                  Alerts(_NAME_, n);
                }
                try{
                    Popup().RefreshResult(c, _NAME_);
                }catch(e){}
                console.log('Chrowety.'+_NAME_+'.Notify(): '+c);
            }
        },

        Run:function(callback){ // Rate Limited
            var _NAME_ = 'home';
            if(!api_limit){
              return false;
            }
            if(Chrowety[_NAME_].RunTrava){
              return;
            }
            console.log('Chrowety.'+_NAME_+'.Run()');
            var Run = new Request(api[_NAME_](), 'get');
                Run.dados = {count:config.start_count[_NAME_]};
                Run.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = true;
                                //> Salva o perfil
                                var U = S2J(db.pega('profile_view'));
                                if(!U[w.user.screen_name]){
                                    var ts = J2S(w.user);
                                    ts = S2J(ts);
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                    U[ts.screen_name] = ts;
                                    db.salva('profile_view', J2S(U));
                                }
                                //
                                if(n == 0){Chrowety[_NAME_].primeiro_lista = taid}
                              });
                              Chrowety[_NAME_]._loaded = true;
                              Chrowety[_NAME_].ultimo = taid;
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                              if(callback){
                                try{eval('Popup().'+callback)}catch(e){}
                              }
                              Chrowety[_NAME_].RunTrava = null;
                }
                Run.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Run() > FAIL');
                    window.setTimeout('Chrowety.'+_NAME_+'.Run(\''+callback+'\')', m(1));
                    Chrowety[_NAME_].RunTrava = null;
                    //Chrowety[_NAME_].Run(callback);
                }
                Run.initOAuth();
                Chrowety[_NAME_].RunTrava = true;
        },
        Since:function(since){ // Rate Limited
            var _NAME_ = 'home';
            if(!api_limit){return false}
            if(Chrowety[_NAME_].SinceTrava){
              return;
            }
            clearInterval(time[_NAME_])
            console.log('Chrowety.'+_NAME_+'.Since()');
            ContaTweets(_NAME_);
            var last = since ? since : Chrowety[_NAME_].ultimo;
            var novs = 0;
            var Since = new Request(api[_NAME_](), 'get');
                Since.dados = {since_id: last};
                Since.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                if(fec.ByTid(_NAME_, w.id)){
                                    return;
                                }
                                n++;
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = false;
                                Utils.Tweet.DetectSaveMention(w, _NAME_);
                                //> Salva o perfil
                                var U = S2J(db.pega('profile_view'));
                                if(!U[w.user.screen_name]){
                                    var ts = J2S(w.user);
                                    ts = S2J(ts);
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                    U[ts.screen_name] = ts;
                                    db.salva('profile_view', J2S(U));
                                }
                                //
                                novs = n;
                              });
                              Chrowety[_NAME_].SinceTrava = null;
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                              console.log('Since++ '+novs);
                              Chrowety[_NAME_].ultimo = taid;
                              console.log('Chrowety.'+_NAME_+'.Since() > New '+novs+' tweets');
                              Chrowety[_NAME_].Notify(novs);
                }
                Since.erro = function(){
                    Chrowety[_NAME_].SinceTrava = null;
                    console.log('Chrowety.'+_NAME_+'.Since() > FAIL');
                    window.setTimeout('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                }
                Since.initOAuth();
                Chrowety[_NAME_].SinceTrava = true;
        },
        Max:function(max){ // Rate Limited
            var _NAME_ = 'home';
            if(!api_limit){return false}
            console.log('Chrowety.'+_NAME_+'.Max()');
            ContaTweets(_NAME_);
            var first = max ? max : Chrowety[_NAME_].primeiro;
            var re = '';
            re = fec.html(_NAME_, {max:first});
            if(!re){
            var Max = new Request(api[_NAME_](), 'get');
                Max.dados = {count: config.old_count[_NAME_], max_id: first};
                Max.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                if(n == 0){return;}
                                taid = w.id;
                                w.read = true;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                oid = id;
                                ht = Layout(w, _NAME_);
                                re = re+ht;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                //> Salva o perfil
                                var U = S2J(db.pega('profile_view'));
                                if(!U[w.user.screen_name]){
                                    var ts = J2S(w.user);
                                    ts = S2J(ts);
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                    U[ts.screen_name] = ts;
                                    db.salva('profile_view', J2S(U));
                                }
                                //
                              });
                              Chrowety[_NAME_].primeiro = taid;
                              Popup().ShowMoreOK(re, _NAME_);
                              console.log('Chrowety.'+_NAME_+'.Max() > Pegou do Online');
                };
                Max.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Max() > FAIL');
                };
                Max.initOAuth();
            }else{
                console.log('Chrowety.'+_NAME_+'.Max() > Pegou do Cache');
                Popup().ShowMoreOK(re, _NAME_);
            }
        },
    },


    mentions: {
        NAME: 'mentions',
        _loaded:false,
        scroll:0,
        mostrando:0,
        ultimo:null,
        primeiro:null,
        primeiro_lista:null,
        RunTrava: null,
        SinceTrava: null,

        Notify:function(n){
            var _NAME_ = 'mentions';
            tws[_NAME_].new_count += n;
            try{Popup().LT.HideLoad()}catch(e){}
            if(tws[_NAME_].new_count > 0){
                var c = tws[_NAME_].new_count;
                MostraCount();
                if(n){
                  Alerts(_NAME_, n);
                }
                try{
                    Popup().RefreshResult(c, _NAME_);
                }catch(e){}
                console.log('Chrowety.'+_NAME_+'.Notify(): '+c);
            }
        },

        Run:function(callback){ // Rate Limited
            var _NAME_ = 'mentions';
            if(!api_limit){return false}
            if(Chrowety[_NAME_].RunTrava){
              return;
            }
            console.log('Chrowety.'+_NAME_+'.Run()');
            var Run = new Request(api[_NAME_](), 'get');
                Run.dados = {count:config.start_count[_NAME_]};
                Run.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = true;
                                //> Salva o perfil
                                var U = S2J(db.pega('profile_view'));
                                if(!U[w.user.screen_name]){
                                    var ts = J2S(w.user);
                                    ts = S2J(ts);
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                    U[ts.screen_name] = ts;
                                    db.salva('profile_view', J2S(U));
                                }
                                //
                                if(n == 0){Chrowety[_NAME_].primeiro_lista = taid}
                              });
                              Chrowety[_NAME_]._loaded = true;
                              Chrowety[_NAME_].ultimo = taid;
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                              if(callback){
                                try{eval('Popup().'+callback)}catch(e){}
                              }
                              Chrowety[_NAME_].RunTrava = null;
                };
                Run.erro = function(){
                    //Chrowety[_NAME_].Run(callback);
                    window.setTimeout('Chrowety.'+_NAME_+'.Run(\''+callback+'\')', m(1));
                    Chrowety[_NAME_].RunTrava = null;
                };
                Run.initOAuth();
                Chrowety[_NAME_].RunTrava = true;
        },
        Since:function(since){ // Rate Limited
            var _NAME_ = 'mentions';
            if(!api_limit){return false}
            if(Chrowety[_NAME_].SinceTrava){
              return;
            }
            clearInterval(time[_NAME_]);
            console.log('Chrowety.'+_NAME_+'.Since()');
            ContaTweets(_NAME_);
            var last = since ? since : Chrowety[_NAME_].ultimo;
            var novs = 0;
            var Since = new Request(api[_NAME_](), 'get');
                Since.dados = {since_id: last};
                Since.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                if(fec.ByTid(_NAME_, w.id)){
                                    return;
                                }
                                n++;
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = false;
                                Utils.Tweet.DetectSaveMention(w, _NAME_);
                                //> Salva o perfil
                                var U = S2J(db.pega('profile_view'));
                                if(!U[w.user.screen_name]){
                                    var ts = J2S(w.user);
                                    ts = S2J(ts);
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                    U[ts.screen_name] = ts;
                                    db.salva('profile_view', J2S(U));
                                }
                                //
                                novs = n;
                              });
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                              console.log('Since++ '+novs);
                              Chrowety[_NAME_].ultimo = taid;
                              console.log('Chrowety.'+_NAME_+'.Since() > New '+novs+' tweets');
                              Chrowety[_NAME_].Notify(novs);
                              Chrowety[_NAME_].SinceTrava = null;
                };
                Since.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Since() > FAIL');
                    window.setTimeout('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                    Chrowety[_NAME_].SinceTrava = null;
                };
                Since.initOAuth();
                Chrowety[_NAME_].SinceTrava = true;
        },
        Max:function(max){ // Rate Limited
            var _NAME_ = 'mentions';
            if(!api_limit){return false}
            console.log('Chrowety.'+_NAME_+'.Max()');
            ContaTweets(_NAME_);
            var first = max ? max : Chrowety[_NAME_].primeiro;
            var re = '';
            re = fec.html(_NAME_, {max:first});
            if(!re){
            var Max = new Request(api[_NAME_](), 'get');
                Max.dados = {count: config.old_count[_NAME_], max_id: first};
                Max.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                if(n == 0){return;}
                                taid = w.id;
                                w.read = true;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                oid = id;
                                ht = Layout(w, _NAME_);
                                re = re+ht;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                              });
                              Chrowety[_NAME_].primeiro = taid;
                              Popup().ShowMoreOK(re, _NAME_);
                };
                Max.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Max() > FAIL');
                };
                Max.initOAuth();
            }else{
                console.log('Chrowety.'+_NAME_+'.Max() > Pegou do Cache');
                Popup().ShowMoreOK(re, _NAME_);
            }
        },

    },


    messages: {
        NAME: 'messages',
        _loaded:false,
        scroll:0,
        mostrando:0,
        ultimo:null,
        primeiro:null,
        primeiro_lista:null,
        RunTrava: null,
        RunSentTrava: null,
        SinceTrava: null,

        Notify:function(n){
            var _NAME_ = 'messages';
            tws[_NAME_].new_count += n;
            try{Popup().LT.HideLoad()}catch(e){}
            if(tws[_NAME_].new_count > 0){
                var c = tws[_NAME_].new_count;
                MostraCount();
                if(n){
                  Alerts(_NAME_, n);
                }
                try{
                    Popup().RefreshResult(c, _NAME_);
                }catch(e){}
                console.log('Chrowety.'+_NAME_+'.Notify(): '+c);
            }
        },

        Run:function(callback, sent){ // Rate Limited
            var _NAME_ = 'messages';
            var _ap;
            if(!api_limit){return false}
            if(sent){
                _ap = 'messagesSent';
                if(Chrowety[_NAME_].RunSentTrava){
                  return;
                }
            }
            else{
                _ap = 'messages';
                if(Chrowety[_NAME_].RunTrava){
                  return;
                }
            }
            console.log('Chrowety.'+_ap+'.Run()');
            var Run = new Request(api[_ap](), 'get');
                Run.dados = {count:config.start_count[_NAME_]};
                Run.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = true;
                                if(n == 0){Chrowety[_NAME_].primeiro_lista = taid}
                              });
                              Chrowety[_NAME_]._loaded = true;
                              Chrowety[_NAME_].ultimo = taid;
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                              if(callback){
                                try{eval('Popup().'+callback)}catch(e){}
                              }
                              if(sent){
                                  Chrowety[_NAME_].RunSentTrava = null;
                              }
                              else{
                                  Chrowety[_NAME_].RunTrava = null;
                              }
                }

                Run.erro = function(){
                    console.log('Chrowety.'+_ap+'.Run() > FAIL');
                    if(sent){
                        Chrowety[_NAME_].RunSentTrava = null;
                        window.setTimeout('Chrowety.'+_NAME_+'.Run(\''+callback+'\', true)', m(1));
                    }
                    else{
                        Chrowety[_NAME_].RunTrava = null;
                        window.setTimeout('Chrowety.'+_NAME_+'.Run(\''+callback+'\')', m(1));
                    }
                }

                Run.initOAuth();
                if(sent){
                    Chrowety[_NAME_].RunSentTrava = true;
                }
                else{
                    Chrowety[_NAME_].RunTrava = true;
                }
        },
        Since:function(since){// Rate Limited
            var _NAME_ = 'messages';
            if(!api_limit){return false}
            if(Chrowety[_NAME_].SinceTrava){
              return;
            }
            clearInterval(time[_NAME_])
            console.log('Chrowety.'+_NAME_+'.Since()');
            ContaTweets(_NAME_);
            var last = since ? since : Chrowety[_NAME_].ultimo;
            var novs = 0;
            var Since = new Request(api[_NAME_](), 'get');
                Since.dados = {since_id: last};
                Since.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                n++;
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = false;
                                novs = n;
                              });
                              Chrowety[_NAME_].SinceTrava = null;
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                              console.log('Since++ '+novs);
                              Chrowety[_NAME_].ultimo = taid;
                              //console.log('Chrowety.'+_NAME_+'.Since() > New '+novs+' tweets');
                              Chrowety[_NAME_].Notify(novs);
                };
                Since.erro = function(){
                    window.setTimeout('Chrowety.'+_NAME_+'.Since()', m(config.refresh[_NAME_]));
                    console.log('Chrowety.'+_NAME_+'.Since() > FAIL');
                    Chrowety[_NAME_].SinceTrava = null;
                };
                Since.initOAuth();
                Chrowety[_NAME_].SinceTrava = true;
        },
        Max:function(max){// Rate Limited
            var _NAME_ = 'messages';
            if(!api_limit){return false}
            console.log('Chrowety.'+_NAME_+'.Max()');
            ContaTweets(_NAME_);
            var first = max ? max : Chrowety[_NAME_].primeiro;
            var re = '';
            re = fec.html(_NAME_, {max:first});
            if(!re){
            var Max = new Request(api[_NAME_](), 'get');
                Max.dados = {count: config.old_count[_NAME_], max_id: first};
                Max.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                if(n == 0){return;}
                                taid = w.id;
                                w.read = true;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                oid = id;
                                ht = LayoutMessage(w, _NAME_);
                                re = re+ht;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                //tws[_NAME_].tweets[tws[_NAME_].total].html = ht;
                              });
                              Chrowety[_NAME_].primeiro = taid;
                              Popup().ShowMoreOK(re, _NAME_);
                };
                Max.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Max() > FAIL');
                };
                Max.initOAuth();
            }else{
                console.log('Chrowety.'+_NAME_+'.Max() > Pegou do Cache');
                Popup().ShowMoreOK(re, _NAME_);
            }
        },

    },

    favorites: {
        NAME: 'favorites',
        _loaded:false,
        scroll:0,
        mostrando:0,
        ultimo:null,
        pagina:1,
        primeiro_lista:null,
        RunTrava: null,
        SinceTrava: null,

        Notify:function(n){
            var _NAME_ = 'messages';
            tws[_NAME_].new_count += n;
            try{Popup().LT.HideLoad()}catch(e){}
            if(tws[_NAME_].new_count > 0){
                var c = tws[_NAME_].new_count;
                var d = tws[_NAME_].new_count+c;
                chrome.browserAction.setBadgeText({text:''+c});
                try{
                  Popup().RefreshResult(d, _NAME_);
                }catch(e){}
                console.log('Chrowety.'+_NAME_+'.Notify(): '+d);
                //ContaTweets(_NAME_);
            }
        },

        Run:function(callback){// Rate Limited
            var _NAME_ = 'favorites';
            if(!api_limit){return false}
            if(Chrowety[_NAME_].RunTrava){
              return;
            }
            console.log('Chrowety.'+_NAME_+'.Run()');
            tws[_NAME_].total = 0;
            var Run = new Request(api[_NAME_](), 'get');
                Run.dados = {page: 1};
                Run.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                taid = w.id;
                                id = w.retweeted_status ? w.retweeted_status.id : w.id;
                                aid = id;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                tws[_NAME_].tweets[tws[_NAME_].total].read = true;
                                //ht = Layout(tws[_NAME_].tweets[tws[_NAME_].total], _NAME_);
                                //tws[_NAME_].tweets[tws[_NAME_].total].html = ht;
                                var U = S2J(db.pega('profile_view'));
                                var ts = J2S(w.user);
                                    ts = S2J(ts); // POG pra tirar relacionamento
                                    ts.status = J2S(w);
                                    ts.status = S2J(ts.status);
                                    delete ts.status.user;
                                U[ts.screen_name] = ts;
                                db.salva('profile_view', J2S(U));
                              });
                              Chrowety[_NAME_].pagina = 1;
                              Chrowety[_NAME_]._loaded = true;
                              clearInterval(time[_NAME_]);
                              time[_NAME_] = setInterval('Chrowety.'+_NAME_+'.Run()', m(config.refresh[_NAME_]));
                              if(callback){
                                try{eval('Popup().'+callback)}catch(e){}
                              }
                              Chrowety[_NAME_].RunTrava = null;
                };
                Run.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Run() > FAIL');
                    clearInterval(time[_NAME_]);
                    //Chrowety[_NAME_].Run(callback);
                    window.setTimeout('Chrowety.'+_NAME_+'.Run(\''+callback+'\')', m(1));
                    Chrowety[_NAME_].RunTrava = null;
                };
                Run.initOAuth();
                Chrowety[_NAME_].RunTrava = true;
        },

        Max:function(pag){// Rate Limited
            var _NAME_ = 'favorites';
            if(!api_limit){return false}
            console.log('Chrowety.'+_NAME_+'.Max()');
            ContaTweets(_NAME_);
            //var pag = pag ? pag : 1;
            Chrowety[_NAME_].pagina += 1;
            var pag = Chrowety[_NAME_].pagina;
            var re = '';
            var Max = new Request(api[_NAME_](), 'get');
                Max.dados = {page: pag};
                Max.sucesso = function(json,s){
                              var id;
                              $.each(json,function(n,w){
                                w.read = true;
                                ht = Layout(w, _NAME_);
                                re = re+ht;
                                tws[_NAME_].total++;
                                tws[_NAME_].tweets[tws[_NAME_].total] = w;
                                //tws[_NAME_].tweets[tws[_NAME_].total].html = ht;
                              });
                              Popup().ShowMoreOK(re, _NAME_);
                };
                Max.erro = function(){
                    console.log('Chrowety.'+_NAME_+'.Max() > FAIL');
                };
                Max.initOAuth();
        },

    },
};



function LayoutMessage(w, time){
  var user = w.sender.screen_name,
  nome = w.sender.name,
  destino = w.recipient.screen_name;
  destinoNome = w.recipient.name;
  txt =  w.text,
  foto = w.sender.profile_image_url,
  data = w.created_at,
  tid = w.id;

  read = w.read ? 'read' : 'unread';
  if(w.reply_backup){
      var reply_backup = w.reply_backup;
  }else{
      var reply_backup = '';
  }

  txt = Utils.Regex.Replace(txt);

  r =
  '<div id="tweply_'+tid+'" class="tweply">' +
            '<div class="twet '+read+'">' +
                '<div class="text">' +
                    '<input id="tid_'+tid+'" value="'+tid+'" type="hidden" />' +
                    '<input id="user_'+tid+'" value="'+user+'" type="hidden" />' +
                    '<input id="data_'+tid+'" value="'+data+'" type="hidden" />' +
                    '<a title="'+nome+' ('+user+')" href="#" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')" class="fl">' +
                      '<img class="photo" src="'+foto+'" width="45" height="45" />' +
                    '</a>' +
                    '<div class="fr">'+
                        '<a title="'+Traduz('translate_this_tweet')+'" onclick="Traduzir('+tid+', \''+time+'\');" class="trans opts">Hover</a>'+
                    '</div>'+
                    '<span title="'+nome+' ('+user+')" class="tweets_names dn" ><a class="usuario" href="#" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')">'+user+'</a>: </span>'+
                    '<span id="texto_'+tid+'" class="texwt" data="'+escape(w.text)+'" html="'+escape(txt)+'">'+txt+'</span>' +
                '</div>' +
                '<div class="cinza">' +
                    '<span title="'+tid+'" class="cinza p8 tweetdata" data="'+data+'"></span>' +
                    ' '+Traduz('to').toLowerCase()+': <a class="usuario" title="'+destinoNome+'" href="#" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+destino+'\')">'+destino+'</a></span>'+
                    '<img id="deleta_load_'+tid+'" class="dn fr" /><span class="opts fr"><a id="deleta_button_'+tid+'" onclick="DeletaDM('+tid+', \''+time+'\');" class="lixo opts fr" title="'+Traduz('delete')+'">'+Traduz('delete')+'</a></span>' +
                '</div>' +
                '<a onclick="ReplyDM('+tid+', \''+time+'\', true);" class="r" title="'+Traduz('reply')+' '+user+'">'+Traduz('reply')+'</a>' +
            '</div>' +
            '<div id="reply_'+tid+'" class="reply dn dm">' +
              '<!--<div class="dm_title">'+
                '<span class="dm_text">DM</span> '+
                '<span class="dm_to">to</span> '+
                '<span class="dm_user">ElinhoLeal</span'+
              '</div><br />-->'+
              '<textarea onkeydown="Atalho(evt, '+tid+', \''+time+'\')" onkeyup="Count('+tid+', \''+time+'\')" id="reply_text_'+tid+'" class="p8" backup="'+reply_backup+'"></textarea><br />' +
              '<span id="reply_rt_'+tid+'" class="dn">' +
                 '<button title="'+Traduz('special_chars')+'" class="button fl bt_char" onclick="SpecialChars.show(\''+tid+'\', \''+time+'\');">&hellip;</button>'+
                 '<span class="short" title="'+Traduz('url_shortener')+'"><button onclick="ShortLink('+tid+', \''+time+'\')"  class="button fl"><img src="img/link.png" height="16" /></button><input onfocus="ShowShortLink('+tid+', \''+time+'\')" _onblur="HideShortLink('+tid+')" active="false" class="short_link_url fl" id="short_link_url_'+tid+'" type="text" /></span><br class="cb"/>' +
                 '<button class="button_margin" id="botao_'+tid+'" onclick="doReplyDM('+tid+', \''+time+'\');" title="'+Traduz('done')+' (Enter)">'+Traduz('done')+'</button>' +
                 '<a onclick="ReplyCancel('+tid+', \''+time+'\')" title="'+Traduz('cancel')+'" class="p8">'+Traduz('cancel')+'</a>' +
              '</span>' +
              '<span id="count_'+tid+'" class="reply_left p13">140</span>' +
              '<span id="reply_status_'+tid+'" class="reply_left"></span>' +
            '</div>' +
    '</div>';
  return r;
}


function Layout(w, time, list){
  if(list){
    time = 'list';
  }
  var user = w.user.screen_name,
  nome = w.user.name,
  classic_txt = escape(w.text);
  txt = w.retweeted_status ? w.retweeted_status.text : w.text,
  foto = w.user.profile_image_url,
  data = w.created_at,
  source = w.source,
  tid =  w.id;
  tid_ = w.id;
  read = w.read ? 'read' : 'unread';

  var in_reply = w.in_reply_to_status_id ? '<a class="cinza p8" href="#" nohref="http://twitter.com/'+w.in_reply_to_screen_name+'/status/'+w.in_reply_to_status_id+'" onclick="Link(this, event);" title="'+Traduz('in_reply_to')+' '+w.in_reply_to_screen_name+'">'+Traduz('in_reply_to')+' '+w.in_reply_to_screen_name+'</a>' : '';
  var Retweeted = '';
  var RT  = '<a onclick="Retweet('+tid+', \''+time+'\');" class="opts fr" title="'+Traduz('retweet')+'">'+Traduz('retweet')+'</a>';
  var Mentionado = (txt.indexOf('@'+db.pega('user')) != -1) ? ( time == "home" ? "mentionado" : "") : "";
  var del = db.pega('user') == user ? '<img id="deleta_load_'+tid+'" class="dn fr" /><span class="opts fr"><a id="deleta_button_'+tid+'" onclick="Deleta('+tid+', \''+time+'\');" class="lixo" title="'+Traduz('delete')+'">'+Traduz('delete')+'</a></span>' : '';
  var GEO = '';

  if(w.user.protected){
    txt = '<span class="cadeado" title="Protected"></span> '+txt;
  }

  if(w.retweeted_by_me){
    var rt_user = db.pega('user');
    Retweeted = '<span id="retweeted_status_'+tid+'"><br /><span class="cinza p8" title="'+Traduz('retweeted_by')+' '+rt_user+'">'+Traduz('retweeted_by')+' </span><span id="retweeted_status_by_me_'+tid+'"><a class="reter p8" nohref="http://twitter.com/'+rt_user+'" onclick="ShowUser(\''+rt_user+'\')" title="'+rt_user+'">'+Traduz('you')+'</a></span></span>';
    RT  = '<a onclick="Deleta('+tid+', \''+time+'\', '+w.retweeted_by_me_status+');" class="opts fr" title="'+Traduz('undo_retweet')+'">'+Traduz('undo_retweet')+'</a>';
  }

  if(w.retweeted_status){
    rt_user = w.user.screen_name;
    rt_user_ = rt_user;

    user = w.retweeted_status.user.screen_name;
    nome = w.retweeted_status.user.name;
    txt = w.retweeted_status.text;
    foto = w.retweeted_status.user.profile_image_url;
    data = w.retweeted_status.created_at;
    source = w.retweeted_status.source;
//    tid = w.retweeted_status.id;
    tid = w.id;
    tid_ = w.retweeted_status.id;
    RT = '<a onclick="RetweetRT('+tid+', \''+time+'\');" class="opts fr" title="'+Traduz('retweet')+'">'+Traduz('retweet')+'</a>';

    in_reply = w.retweeted_status.in_reply_to_status_id ?
    '<a class="cinza p8" href="#" nohref="http://twitter.com/'+w.retweeted_status.in_reply_to_screen_name+'/status/'+w.retweeted_status.in_reply_to_status_id+'" onclick="Link(this, event);" title="'+Traduz('in_reply_to')+' '+w.retweeted_status.in_reply_to_screen_name+'">'+Traduz('in_reply_to')+' '+w.retweeted_status.in_reply_to_screen_name+'</a>'
    : '';

    txt = '<span class="rts" title="'+Traduz('retweeted_by')+' '+rt_user+'">Retweeted</span> <a class="reter" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')">'+user+'</a> '+txt;
    Retweeted = '<span id="retweeted_status_'+tid+'"><br /><span class="cinza p8" title="'+Traduz('retweeted_by')+' '+rt_user+'">'+Traduz('retweeted_by')+' </span><span id="retweeted_status_by_other_'+tid+'"><a class="reter p8" nohref="http://twitter.com/'+rt_user+'" onclick="ShowUser(\''+rt_user+'\')" title="'+rt_user+'">'+rt_user_+'</a></span';
    if(w.retweeted_by_me){
      var rt_user = db.pega('user');
      Retweeted += '<span id="retweeted_status_by_me_'+tid+'">, <a class="reter p8" nohref="http://twitter.com/'+rt_user+'" onclick="ShowUser(\''+rt_user+'\')" title="'+rt_user+'">'+Traduz('you')+'</a></span></span>';
      RT  = '<a onclick="Deleta('+tid+', \''+time+'\', '+w.retweeted_by_me_status+');" class="opts fr" title="'+Traduz('undo_retweet')+'">'+Traduz('undo_retweet')+'</a>';
    }else{
      Retweeted += '</span>';
    }
    Retweeted += ' <span class="opts2">(<span class="cinza p8 tweetdata" data="'+w.created_at+'"></span>)</span>';

  }

  RT = db.pega('user') == user ? '' : RT;

  var fav = w.favorited ? '<a id="tweet_fav_'+tid+'" class="star" fav="true" onclick="UnFavorite('+tid+', \''+time+'\')" title="'+Traduz('unfavorite')+'">'+Traduz('unfavorite')+'</a><img id="tweet_ifav_'+tid+'" src="" class="dn" />' :
                      '<a id="tweet_fav_'+tid+'" class="star opts" onclick="Favorite('+tid+', \''+time+'\')" title="'+Traduz('favorite')+'">'+Traduz('favorite')+'</a><img id="tweet_ifav_'+tid+'" src="" class="dn" />';

  var dm = db.pega('user') == user ? '' : '<a class="msg opts" onclick="ReplyDM('+tid+', \''+time+'\', true)" title="DM '+Traduz('to')+' '+user+'">'+Traduz('messages')+'</a>';

  txt = Utils.Regex.Replace(txt);

  txt = txt.replace('>@'+db.pega('user'), ' class="usuario photo bold">@'+db.pega('user'));

  w.html_tweet = txt;
  source = source.replace('rel=\"nofollow\"', 'class="cinza p8 source" onclick="Link(this, event);"');
  source = source.replace('href=', 'href="#" nohref=');
  var careator = !w.retweeted_status ?
                    '<a title="'+nome+' ('+user+')" href="#" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')">'+
                        '<span class="creator">'+user+'</span>'+
                    '</a><br />' : '';
  var creator = '';

  if(w.reply_backup){
    var reply_backup = w.reply_backup;
    //var reply_backup = '';
    var cdn = 'dn'
  }else{
    var reply_backup = '';
    var cdn = 'dn';
  }

  if(w.geo){
    if(w.geo.coordinates){
        var coo = w.geo.coordinates.join(',');
        GEO = '<a title="'+Traduz('show_geo_location')+'" onclick="Map(\''+coo+'\', '+tid+', \''+time+'\');" class="location">Geo</a>';
    }
  }

  r =
  '<div id="tweply_'+tid+'" class="tweply">' +
            '<div class="twet '+read+' '+Mentionado+'">' +
                '<div class="text">' +
                    '<input id="tid_'+tid+'" value="'+tid+'" type="hidden" />' +
                    '<input id="user_'+tid+'" value="'+user+'" type="hidden" />' +
                    '<input id="data_'+tid+'" value="'+data+'" type="hidden" />' +
                    '<a title="'+nome+' ('+user+')" href="#" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')" class="fl">' +
                      '<img class="photo" alt="'+nome+'\'s Picture" src="'+foto+'" width="45" height="45" />' +
                    '</a>' +
                    creator+
                    '<div class="fr">'+
                        fav+
                        dm+
                        '<a title="'+Traduz('translate_this_tweet')+'" onclick="Traduzir('+tid+', \''+time+'\');" class="trans opts">Hover</a>'+
                    '</div>'+
					(!w.retweeted_status ? '<span class="tweets_names dn" ><a class="usuario" title="'+nome+' ('+user+')" href="#" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')">'+user+'</a>: </span>':'')+
                    '<span id="texto_'+tid+'" class="texwt" data="'+classic_txt+'" html="'+escape(txt)+'">'+txt+'</span>' +
                '</div>' +
                '<div class="cinza">' +
                    '<span>'+GEO+'<a title="'+tid+'" class="cinza p8 tweetdata" href="#" nohref="http://twitter.com/'+user+'/status/'+tid_+'" onclick="Link(this, event);" data="'+data+'"></a></span>' +
                    '<span id="data_rt_'+tid+'">'+
                        ' <span class="cinza p8">'+Traduz('from')+'</span> '+source+' ' +
                        in_reply +
    					Retweeted +
                    '</span>'+
                    '<span id="data_retweet_'+tid+'">'+
                        RT +
                        del +
                    '</span>'+
                '</div>' +
                '<a tid="'+tid+'" time="'+time+'" onclick="Reply('+tid+', false, \''+time+'\');" class="r click_to_reply" title="'+Traduz('reply')+' '+user+'">'+Traduz('reply')+'</a>' +
            '</div>' +

            '<div id="reply_'+tid+'" class="reply '+cdn+'">' +
              '<textarea onkeydown="Atalho(event, '+tid+', \''+time+'\')" onkeyup="Count('+tid+', \''+time+'\')" id="reply_text_'+tid+'" class="p10" backup="'+reply_backup+'"></textarea><br/>' +
              '<span id="retweet_choice_'+tid+'" class="dn">' +
                  '<br />'+
                  '<button class="button_margin" id="rt_now_'+tid+'" onclick="RetweetOficial('+tid+', \''+time+'\')" title="'+Traduz('retweet_now')+'">'+Traduz('retweet_now')+'</button>' +
                  '<button class="button_margin" id="edit_rt_'+tid+'" onclick="RetweetEdit('+tid+', \''+time+'\');" title="'+Traduz('edit')+'">'+Traduz('edit')+'</button>' +
                  '<a onclick="ReplyCancel('+tid+', \''+time+'\')" class="p8" title="'+Traduz('cancel')+'">'+Traduz('cancel')+'</a>' +
              '</span>' +
              '<span id="reply_rt_'+tid+'" class="dn">' +
                 '<button title="'+Traduz('special_chars')+'" class="button fl bt_char" onclick="SpecialChars.show(\''+tid+'\', \''+time+'\');">&hellip;</button>'+
                 '<span class="short" title="'+Traduz('url_shortener')+'"><button onclick="ShortLink('+tid+', \''+time+'\')"  class="button fl"><img src="img/link.png" height="16" /></button><input onfocus="ShowShortLink('+tid+', \''+time+'\')" _onblur="HideShortLink('+tid+')" active="false" class="short_link_url fl" id="short_link_url_'+tid+'" type="text" /></span><br class="cb"/>' +
                 '<button class="button_margin" id="botao_'+tid+'" onclick="doReply('+tid+', \''+time+'\');" title="'+Traduz('done')+' (Enter)">'+Traduz('done')+'</button>' +
                 '<a id="botao_'+tid+'_cancel" onclick="ReplyCancel('+tid+', \''+time+'\')" title="'+Traduz('cancel')+'" class="p8">'+Traduz('cancel')+'</a>' +
              '</span>' +
              '<span id="count_'+tid+'" class="reply_left p13">140</span>' +
              '<span id="reply_status_'+tid+'" class="reply_left state"></span>' +
            '</div>' +
    '</div>';
  return r;
}


function LayoutPage(w, time){
  if(time == 'messages'){
      var user = w.sender.screen_name,
      nome = w.sender.name,
      classic_txt = '';
      txt =  w.text,
      foto = w.sender.profile_image_url,
      data = w.created_at,
      source = '',
      tid = w.id;
  }else{
      var user = w.user.screen_name,
      nome = w.user.name,
      classic_txt = w.retweeted_status ? w.text : '';
      txt = w.retweeted_status ? w.retweeted_status.text : w.text,
      foto = w.user.profile_image_url,
      data = w.created_at,
      source = w.source,
      tid = w.id;
  }


  read = w.read ? 'read' : 'unread';

  var in_reply = w.in_reply_to_status_id ? '<a class="cinza p8" href="http://twitter.com/'+w.in_reply_to_screen_name+'/status/'+w.in_reply_to_status_id+'" target="_blank" title="'+Traduz('in_reply_to')+' '+w.in_reply_to_screen_name+'">'+Traduz('in_reply_to')+' '+w.in_reply_to_screen_name+'</a>' : '';
  var Retweeted = '';
  var RT  = '<a onclick="Retweet('+tid+', \''+time+'\');" class="opts fr" title="'+Traduz('retweet')+'">'+Traduz('retweet')+'</a>';

  if(w.retweeted_status){
    rt_user = w.user.screen_name;

    RT = db.pega('user') == user ? '' : RT;
    user = w.retweeted_status.user.screen_name;
    nome = w.retweeted_status.user.name;
    txt = w.retweeted_status.text;
    foto = w.retweeted_status.user.profile_image_url;
    data = w.retweeted_status.created_at;
    source = w.retweeted_status.source;
    tid = w.retweeted_status.id;
    in_reply = w.retweeted_status.in_reply_to_status_id ?
    '<a class="cinza p8" href="http://twitter.com/'+w.retweeted_status.in_reply_to_screen_name+'/status/'+w.retweeted_status.in_reply_to_status_id+'" target="_blank" title="'+Traduz('in_reply_to')+' '+w.retweeted_status.in_reply_to_screen_name+'">'+Traduz('in_reply_to')+' '+w.retweeted_status.in_reply_to_screen_name+'</a>'
    : '';
    txt = '<span class="rts" title="'+Traduz('retweeted_by')+' '+rt_user+'">Retweeted</span> <a class="reter" href="http://twitter.com/'+user+'" target="_blank"'+user+'</a> '+txt;
    Retweeted = '<br /><span class="cinza p8" title="'+Traduz('retweeted_by')+' '+rt_user+'">'+Traduz('retweeted_by')+' </span><a class="reter p8 user" href="http://twitter.com/'+rt_user+'" target="_blank">'+rt_user+'</a>';
    Retweeted += ' <span class="opts2">(<span class="cinza p8 tweetdata" data="'+w.created_at+'">'+TweetData(w.created_at)+'</span>)</span>';
    RT = '<a onclick="RetweetRT('+tid+', \''+time+'\');" class="opts fr" title="'+Traduz('retweet')+'">'+Traduz('retweet')+'</a>';
  }

  var fav = w.favorited ? '<a id="tweet_fav_'+tid+'" class="star fr" fav="true" onclick="UnFavorite('+tid+', \''+time+'\')" title="'+Traduz('unfavorite')+'">'+Traduz('unfavorite')+'</a><img id="tweet_ifav_'+tid+'" src="" class="fr dn">' :
                      '<a id="tweet_fav_'+tid+'" class="star opts fr" onclick="Favorite('+tid+', \''+time+'\')" title="'+Traduz('favorite')+'">'+Traduz('favorite')+'</a><img id="tweet_ifav_'+tid+'" src="" class="fr dn">';

  var del = db.pega('user') == user ? '<a onclick="Deleta('+tid+', \''+time+'\');" class="lixo opts fr" title="'+Traduz('delete')+'">'+Traduz('delete')+'</a>' : '';

  // Links Normais
  txt = txt.replace(/(^|&lt;|\s)(((https?|ftp):\/\/|mailto:).+?^twitpic^tweetphoto^pic.gd^youtube.com\/watch\?v=)(\s|&gt;|$)/g,' <a class="url" title="$2" href="$2" onclick="Link(this, event);" target="_blank">$2</a> ');

  //Twitpic
  txt = txt.replace(/((https?):\/\/twitpic.com\/([a-zA-Z_0-9]*|$))/g,' <a class="url" nohref="$1" title="$1" target="_blank">$1</a>');

  //Tweetphoto | Pic.gd
  txt = txt.replace(/((https?):\/\/(tweetphoto.com\/|www.tweetphoto.com\/|pic.gd\/)([a-zA-Z_0-9]*|$))/g,' <a class="url" nohref="$1" title="$1" target="_blank">$1</a>');

  //YouTube http://www.youtube.com/watch?v=sG5lpGdNd5E
  txt = txt.replace(/((https?):\/\/(www.youtube.com\/watch\?v=|youtube.com\/watch\?v=)([a-zA-Z_0-9]*|$))/g,' <a class="url" nohref="$1" title="$1" target="_blank">$1</a>');


  //Links sem Http
  txt = txt.replace(/(^|&lt;|\s)((www).+?)(\s|&gt;|$)/g,' <a class="url" title="$2" href="http://$2" target="_blank">$2</a> ');

  //Links de Usuarios
  txt = txt.replace(/(@|$)([a-zA-Z_0-9]*|$)/g,' $1<a class="user" title="$2" href="http://twitter.com/$2" target="_blank">$2</a>');

  // Links Normais
  txt = txt.replace(/(^|&lt;|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|&gt;|$)/g,' <a class="url" title="$2" href="$2" target="_blank">$2</a> ');

  //Links de Tags
  txt = txt.replace(/(^|&lt;|a-zA-Z_0-9|\s)(#|$)([_a-zA-Z_0-9]*|$)/g,' $2<a class="tag" title="$3" href="http://twitter.com/search?q=%23$3" target="_blank">$3</a>');

  txt = txt.replace('>@'+db.pega('user'), ' class="usuario photo bold">@'+db.pega('user'));

  source = source.replace('rel=\"nofollow\"', 'class="cinza p8 source" target="_blank"');
  var careator = !w.retweeted_status ?
                    '<a title="'+nome+'" nohref="http://twitter.com/'+user+'" target="_blank">'+
                        '<span class="creator">'+user+'</span>'+
                    '</a><br />' : '';
  var creator = '';

  if(w.reply_backup){
    var reply_backup = w.reply_backup;
    //var reply_backup = '';
    var cdn = 'dn'
  }else{
    var reply_backup = '';
    var cdn = 'dn';
  }

  r =
  '<div id="tweply_'+tid+'" class="tweply" title="'+nome+' ('+user+')">' +
            '<div class="twet '+read+'">' +
                '<div class="text">' +
                    '<input id="tid_'+tid+'" value="'+tid+'" type="hidden" />' +
                    '<input id="user_'+tid+'" value="'+user+'" type="hidden" />' +
                    '<input id="data_'+tid+'" value="'+data+'" type="hidden" />' +
                    '<a title="'+nome+'" href="http://twitter.com/'+user+'" target="_blank" class="fl">' +
                      '<img class="photo" alt="'+nome+'\'s Picture" title="'+nome+' Avatar" src="'+foto+'" width="45" height="45" />' +
                    '</a>' +
                    creator+
                    //fav+
					(!w.retweeted_status ? '<a class="tweets_names usuario" title="'+user+'" nohref="http://twitter.com/'+user+'" onclick="ShowUser(\''+user+'\')">'+user+'</a>: ':'')+
                    '<span id="texto_'+tid+'" class="texwt" data="'+classic_txt+'">'+txt+'</span>' +
                '</div>' +
                '<div class="cinza">' +
                    '<span><a title="'+tid+'" class="cinza p8 tweetdata" href="http://twitter.com/'+user+'/status/'+tid+'" target="_blank" data="'+data+'">'+TweetData(data)+'</a></span>' +
                    (time == 'messages' ? '' : ' via '+source+' ') +
                    in_reply +
                    Retweeted +
                    '<span class="fr">'+Traduz(time)+'</span>' +
                '</div><br />' +
            '</div>' +
    '</div><br />';
  return r;
}

function pause(ms) {
	var dt = new Date();
	while ((new Date()) - dt <= ms){}
}

function LayoutNotifications(w, time){
    if(time == 'messages'){
        var user = w.sender.screen_name,
        tid = w.id,
        nome = w.sender.name,
        classic_txt = '';
        txt =  w.text,
        foto = w.sender.profile_image_url,
        data = '<span class="data">'+TweetData(w.created_at)+'</span>',
        from = '',
        source = '';
    }else{
        var user = w.user.screen_name,
        tid = w.id,
        nome = w.user.name,
        classic_txt = w.retweeted_status ? w.text : '';
        txt = w.retweeted_status ? 'RT @'+w.retweeted_status.user.screen_name+': '+w.retweeted_status.text : w.text,
        foto = w.user.profile_image_url,
        data = '<a href="http://twitter.com/'+user+'/status/'+tid+'" target="_blank" class="data">'+TweetData(w.created_at)+'</a>',
        from = Traduz('from'),
        source = w.source;
    }

    source = source.replace('rel=\"nofollow\"', 'class="data" target="_blank"');

    txt = txt.replace(/(^|&lt;|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|&gt;|$)/g,' <a class="url" title="$2" href="$2" target="_blank" onclick="load()">$2</a> ');
    txt = txt.replace(/(^|&lt;|\s)((www).+?)(\s|&gt;|$)/g,' <a class="url" title="$2" href="http://$2" target="_blank" onclick="load()">$2</a> ');
    txt = txt.replace(/(@|$)([a-zA-Z_0-9]*|$)/g,' $1<a class="user" title="$2" href="http://twitter.com/$2" target="_blank" onclick="load()">$2</a>');
    txt = txt.replace(/(^|&lt;|a-zA-Z_0-9|\s)(#|$)([çÇáéíóúýÁÉÍÓÚÝàèìòùÀÈÌÒÙãõñäëïöüÿÄËÏÖÜÃÕÑâêîôûÂÊÎÔÛ_a-zA-Z_0-9]*|$)/g,' $2<a class="tag" title="$3" href="http://twitter.com/search?q=%23$3" target="_blank" onclick="load()">$3</a>');

    var in_reply = w.in_reply_to_status_id ? '<a class="data" href="http://twitter.com/'+w.in_reply_to_screen_name+'/status/'+w.in_reply_to_status_id+'" target="_blank" title="'+Traduz('in_reply_to')+' '+w.in_reply_to_screen_name+'">'+Traduz('in_reply_to')+' '+w.in_reply_to_screen_name+'</a>' : '';

    var Timeout = s(config.desktop_notifications_timeout);

    var Lay =
        '<scr'+'ipt>Timeout = '+Timeout+';</scr'+'ipt>'+
        '<div class="tweet">'+
            '<a title="'+nome+'" href="http://twitter.com/'+user+'" target="_blank" class="nome">'+
                '<img class="foto fl" src="'+foto+'" width="45" height="45" />'+
                user+
            '</a>'+
            '<div class="texto">'+
                txt+
            '</div>'+
            '<div class="cb">'+
                '<span class="fl">'+
                    data+
                    '<span class="data"> '+from+' </span>'+
                    '<a class="data">'+source+'</a>'+
                '</span>'+
                '<span class="data fr">'+Traduz(time)+'</span>'+
            '</div>'+
            '<br />'+
        '</div>'
    ;
    return Lay;
}

function Alerts(tm, n){
  Utils.Notify.Build(n,tm);

  if(config.audio_alerta == "true"){
      if(AlertaAudioFile.src){
        AlertaAudioFile.play();
      }
      else{
        AlertaAudioFile.src = api.audio;
        AlertaAudioFile.play();
      }
  }

  if(config.alerts == "true"){
      chrome.windows.getAll({}, function(w){
            chrome.tabs.getSelected(w[0].id, function(Taby){
                if(!Taby.url.match('chrome-extension://') && !Taby.url.match('chrome://')){
                    chrome.tabs.executeScript(Taby.id, {
                           file: 'js/jquery-1.4.2.min.js'
                          }, function() {
                              chrome.tabs.insertCSS(Taby.id, {
                                     file: 'css/base_pagina.css'
                                    }, function() {
                                        chrome.tabs.executeScript(Taby.id, {code:
                                          'var _NAME_ = "'+tm+'"; var _TOTAL_ = "'+n+'";var _MAX_ = "'+config.alerts_max+'"; var _Alerts_ = "'+Traduz('alerts')+'";'
                                        });
                                        chrome.tabs.executeScript(Taby.id, {
                                               file: 'js/script.js'
                                        });
                                    }
                              );
                          }
                    );
                }
            });
      });
  }
}

var RGX = {
  link: /(^|&lt;|\s)(((https?|ftp):\/\/|mailto:).+?^twitpic^tweetphoto^pic.gd^youtube.com^yfrog.com^yfrog.us^twitgoo.com\/watch\?v=)(\s|&gt;|$)/g,
  twitpic: /((https?):\/\/twitpic.com\/([a-zA-Z_0-9]*|$))/g,
  twigoo: /((https?):\/\/twitgoo.com\/([a-zA-Z_0-9]*|$))/g,
  yfrog: /((https?):\/\/(yfrog.com|yfrog.us)\/([a-zA-Z_0-9]*|$))/g,
  picgd: /((https?):\/\/(tweetphoto.com\/|www.tweetphoto.com\/|pic.gd\/)([a-zA-Z_0-9]*|$))/g,
  youtube: /((https?):\/\/(www.youtube.com\/watch\?v=|youtube.com\/watch\?v=)([*a-zA-Z_0-9-]*|$)([&_a-zA-Z_0-9-=]*|$))/g,
  twitcam: /((https?):\/\/(www.twitcam.com\/|twitcam.com\/)([\)*a-zA-Z_0-9-]*|$))/g,
  twitvid: /((https?):\/\/(www.twitvid.com\/|twitvid.com\/)([\)*a-zA-Z_0-9-]*|$))/g,
  vimeo: /((https?):\/\/(www.vimeo.com\/|vimeo.com\/)([0-9]*|$))/g,
  youtu: /((https?):\/\/(youtu.be\/|www.youtu.be\/)([*a-zA-Z_0-9-]*|$)([?_a-zA-Z_0-9-=]*|$))/g,
  nohttp: /(^|&lt;|\s)((www).+?)(\s|&gt;|$)/g,
  link2: /(^|&lt;|\s)(((https?|ftp):\/\/|mailto:).+?)(\s|&gt;|$)/g,
  user: /(@|$)([a-zA-Z_0-9]{1,20}|$)/g,
  hash: /(^|&lt;|a-zA-Z_0-9|\s)(#|$)([çÇáéíóúýÁÉÍÓÚÝàèìòùÀÈÌÒÙãõñäëïöüÿÄËÏÖÜÃÕÑâêîôûÂÊÎÔÛ_a-zA-Z_0-9]*|$)/g
}

var Utils = {

    Tweet: {
        DetectSaveMention:function(TweetObj, from){//Utils.Tweet.DetectSaveMention()
            if(typeof TweetObj != 'object'){
                return false;
            }
            var w = TweetObj,tm;
            if(from == 'home'){
                tm = 'mentions'
            }else if(from == 'mentions'){
                tm = 'home';
            }else{
                return;
            }
            if(w.text.indexOf('@'+db.pega('user')) != -1){
                tws[tm].total++;
                tws[tm].tweets[tws[tm].total] = w;
                tws[tm].tweets[tws[tm].total].read = true;
                return true;
            }else{
                return false;
            }
        }
    },

    Drafts: {
        createTable: function(){
            if(!db.pega('drafts')){
                Database.createTable('drafts', ['id INTEGER PRIMARY KEY ASC', 'usuario TEXT', 'texto TEXT', 'data DATETIME'], function(t,r){
                    db.salva('drafts', true);
                });
            }
        },
        salva: function(txt){
            this.createTable();
            Database.insert('drafts', {usuario: db.pega('user'), texto: txt, data: 'NOW()'});
        },
        pega: function(callback){
            this.createTable();
            var html = '';
            Database.select('drafts', null, function(t,re){
                var total = re.rows.length,item;
                for(var i=0; i < total; i++){
                    item = re.rows.item(i);
                    //console.log(item.texto);
                    //html += LayoutDraft(item);
                    html += '<span>'+item.texto+'</span>';
                }
                if(typeof callback == 'function') callback(html)
                return html;
            });
        },
        deleta: function(id){
            this.createTable();
            Database.remove('drafts', (id?'WHERE id='+id:null), function(t,re){
                //re.rowsAffected
            });
        }
    },

    Sistema:{
        so: null,
        load:function(){
            var so, ap = navigator.appVersion;
            if(ap.indexOf("Win")!=-1){
                so = "Windows";
            }
            else if(ap.indexOf("Mac")!=-1){
                so = "Mac";
            }
            else if(ap.indexOf("Linux")!=-1){
                so = "Linux";
            }else{
                so = 'Seila';
            }
            Utils.Sistema.so = so;
            return so;
        }
    },

    Regex:{
        Replace: function(txt){
            if(!txt){
                return txt;
            }else{
                var hrf = 'nohref';
                var clk = true;
                txt = txt.replace(RGX.link,' <a class="url" title="$2" href="#" nohref="$2" onclick="Link(this, event);">$2</a> ');
                txt = txt.replace(RGX.twitpic,' <a class="url" nohref="$1" title="$1" onclick="Twitpic(\'$3\');">$1</a>');
                txt = txt.replace(RGX.twigoo,' <a class="url" nohref="$1" title="$1" onclick="Twitgoo(\'$3\');">$1</a>');
                txt = txt.replace(RGX.yfrog,' <a class="url" nohref="$1" title="$1" onclick="Yfrog(\'$4\');">$1</a>');
                txt = txt.replace(RGX.picgd,' <a class="url" nohref="$1" title="$1" onclick="Tweetphoto(\'$1\');">$1</a>');
                txt = txt.replace(RGX.youtube,' <a class="url" nohref="$1" title="$4" onclick="Youtube(\'$4\');">$1</a>');
                txt = txt.replace(RGX.twitcam,' <a class="url" nohref="$1" title="$4" onclick="Twitcam(\'$4\');">$1</a>');
                txt = txt.replace(RGX.twitvid,' <a class="url" nohref="$1" title="$4" onclick="Twitvid(\'$4\');">$1</a>');
                txt = txt.replace(RGX.vimeo,' <a class="url" nohref="$1" title="$4" onclick="Vimeo(\'$4\');">$1</a>');
                txt = txt.replace(RGX.youtu,' <a class="url" nohref="$1" title="$4" onclick="Youtube(\'$4\');">$1</a>');
                txt = txt.replace(RGX.nohttp,' <a class="url" title="$2" href="#" nohref="http://$2" onclick="Link(this, event);">$2</a> ');
                txt = txt.replace(RGX.user,' $1<a class="usuario" title="$2" nohref="http://twitter.com/$2" onclick="ShowUser(\'$2\')">$2</a>');
                txt = txt.replace(RGX.link2,' <a class="url" title="$2" href="#" nohref="$2" onclick="Link(this, event);">$2</a> ');
                txt = txt.replace(RGX.hash,' $2<a class="tag" title="$3" nohref="http://twitter.com/search?q=%23$3" onclick="Link(this, event);">$3</a>');
                return txt;
            }
        }
    },

    FormataNumero: function(nStr){
    	nStr += '';
    	x = nStr.split('.');
    	x1 = x[0];
    	x2 = x.length > 1 ? '.' + x[1] : '';
    	var rgx = /(\d+)(\d{3})/;
    	while (rgx.test(x1)) {
    		x1 = x1.replace(rgx, '$1' + ',' + '$2');
    	}
    	return x1 + x2;
    },

    Popup:{
        window:null
    },

    Notify:{
        Show:function(data){
            data = escape(data);
            var Notf = webkitNotifications.createHTMLNotification(chrome.extension.getURL('alerta.html')+'#'+data);
            Notf.show();
        },

        Build:function(n, tm){
            if(config.desktop_notifications == 'true'){
                var tws = fec.lastNotifications(tm, n, config.alerts_max), tw;
                for(i in tws){
                    tw = tws[i];
                    this.Show(tw);
                }
            }
        }
    },

    currentURL:null,

    GetTabUrl: function(){
        chrome.tabs.getSelected(null, function(tab) {
               Utils.currentURL = tab.url;
               return tab.url;
        });
    },

    Translate:{
        loaded:false,

        load:function(resp){
            var JSAPI = document.createElement('script');
                JSAPI.src = 'http://www.google.com/jsapi';
                JSAPI.onload = function(){
                    google.load("language", "1", {
                        callback:function(){
                            Utils.Translate.loaded = true;
                            if(resp) resp();
                        }
                    });
                };
                document.head.appendChild(JSAPI);
        },

        trans:function(txt, tid, tm, list){
            if(!this.loaded){
                this.load(function(){
                    Utils.Translate.trans(txt, tid, tm, list);
                });
                return;
            }

            if(list){
                var tweet = fec.ByTid(tm, tid, null, list);
                if(tweet.translated){
                    Popup().TraduzirOK(tweet.translated, tid, tm);
                    return;
                }
            }else{
                var tweet = fec.ByTid(tm, tid);
                if(tweet.translated){
                    Popup().TraduzirOK(tweet.translated, tid, tm);
                    return;
                }
            }


            var Lingua = config.translate_tweets_to;
            google.language.detect(txt, function(re) {
              if(!re.error && re.language){
                google.language.translate(txt, re.language, Lingua, function(re){
                  if(re.translation){
                    var txt = re.translation;
                    txt = txt.replace('@ ', '@');
                    txt = txt.replace('# ', '#');
                    txt = Utils.Regex.Replace(txt);
                    tweet.translated = txt;
                    try{
                      Popup().TraduzirOK(txt, tid, tm);
                    }
                    catch(e){console.log(e)}
                  }else{
                    try{
                      Popup().TraduzirFAIL(re, tid, tm);
                    }
                    catch(e){console.log(e)}
                  }
                });
              }
            });

        }

    },

    Long:{

        Untrim:function(ShortUrl, tid, tm){
            var Un = new Request(api.untrim, 'post', 'html');
                Un.dados = {url: ShortUrl};
                Un.sucesso = function(re){
                    console.log(re);
                    var url = re.getElementsByTagName('a');
                    url = url[url.length-1].innerText;
                    console.log(url);
                    //Popup().ShortLinkOK(tid, tm, url);
                };
                Un.erro = function(e){
                    console.log('Ouve um erro no Untr.im');
                };
                Un.init();
        }
    },

    Short:{

      title:null,
      link:null,

      short:function(LongUrl, tid, tm, cb){
        switch(config.url_shortener){
            case '3.ly':
                LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.Threely(LongUrl, tid, tm, null, cb);
                break;
            case 'migre.me':
                LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.MigreMe(LongUrl, tid, tm, cb);
                break;
            case 'goo.gl':
                Utils.Short.GooGl(LongUrl, tid, tm, cb);
                break;
            case 'bit.ly':
                Utils.Short.BitLy(LongUrl, tid, tm, null, cb);
                break;
            case 'j.mp':
                Utils.Short.BitLy(LongUrl, tid, tm, true, cb);
                break;
            case 'is.gd':
                LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.Threely(LongUrl, tid, tm, 'isgd', cb);
                break;
            case 'tr.im':
                LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.Threely(LongUrl, tid, tm, 'trim', cb);
                break;
            case 'urli':
                //LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.Threely(LongUrl, tid, tm, 'urli', cb);
                break;
            case 'miudin':
                //LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.Threely(LongUrl, tid, tm, 'miudin', cb);
                break;
            default:
                LongUrl = encodeURIComponent(LongUrl);
                Utils.Short.Threely(LongUrl, tid, tm, null, cb);
        }
      },
	  
      GooGl:function(LongUrl, tid, tm, callback){
        console.log('Shorting URL: '+LongUrl+' With: Goo.gl');
        this.Auth = function(f){function k(){for(var c=0,b=0;b<arguments.length;b++)c=c+arguments[b]&4294967295;return c}function m(c){c=c=String(c>0?c:c+4294967296);var b;b=c;for(var d=0,i=false,j=b.length-1;j>=0;--j){var g=Number(b.charAt(j));if(i){g*=2;d+=Math.floor(g/10)+g%10}else d+=g;i=!i}b=b=d%10;d=0;if(b!=0){d=10-b;if(c.length%2==1){if(d%2==1)d+=9;d/=2}}b=String(d);b+=c;return b}function n(c){for(var b=5381,d=0;d<c.length;d++)b=k(b<<5,b,c.charCodeAt(d));return b}function o(c){for(var b=0,d=0;d<c.length;d++)b=k(c.charCodeAt(d),b<<6,b<<16,-b);return b}f={byteArray_:f,charCodeAt:function(c){return this.byteArray_[c]}};f.length=f.byteArray_.length;var e=n(f.byteArray_);e=e>>2&1073741823;e=e>>4&67108800|e&63;e=e>>4&4193280|e&1023;e=e>>4&245760|e&16383;var l="7";f=o(f.byteArray_);var h=(e>>2&15)<<4|f&15;h|=(e>>6&15)<<12|(f>>8&15)<<8;h|=(e>>10&15)<<20|(f>>16&15)<<16;h|=(e>>14&15)<<28|(f>>24&15)<<24;l+=m(h);return l};
        var shorted;
        var Goo = new Request(api.googl, 'post');
            Goo.dados = {
                user:'toolbar@google.com',
                url: LongUrl,
                auth_token: this.Auth(LongUrl)
            },
            Goo.sucesso = function(re){
                var url = re.short_url;
                Utils.Short.link = url;
                shorted = url;
                console.log(url);
                if(!callback){
                    Popup().ShortLinkOK(tid, tm, url);
                }else{
                    console.log('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                    eval('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                }
            };
            Goo.erro = function(e){
                console.log('Erro no Goo.gl');
                console.log(e.responseText);
                Popup().ShortLinkOK(tid, tm, '');
            };
            Goo.init();
        return shorted;
      },

      BitLy:function(LongUrl, tid, tm, jmp, callback){
        console.log('Shorting URL: '+LongUrl+' With: BitLy');
        var shorted;
        var ap = jmp ? api.jmp_short : api.bitly_short;
        var Bit = new Request(ap, 'get', 'json');
            Bit.dados = {
              longUrl: LongUrl,
              apiKey: config.bitly_key,
              login: config.bitly_user,
              version: '2.0.1'
            };
            Bit.sucesso = function(re){
                var url = re.results[LongUrl].shortUrl;
                url = url ? url : '';
                Utils.Short.link = url;
                shorted = url;
                console.log(url);
                if(!callback){
                    Popup().ShortLinkOK(tid, tm, url);
                }else{
                    console.log('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                    eval('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                }
            };
            Bit.erro = function(e){
                console.log('Erro no BitLy');
                console.log(e.responseText);
                Popup().ShortLinkOK(tid, tm, '');
            };
            Bit.init();
        return shorted;
      },

      MigreMe:function(LongUrl, tid, tm, callback){
        console.log('Shorting URL: '+LongUrl+' With: Migre.me');
        var shorted;
        var Mi = new Request(api.migre_short, 'get', 'xml');
            Mi.dados = {url: LongUrl};
            Mi.sucesso = function(re){
                var url = $('item > migre', $(re)).text();
                Utils.Short.link = url;
                shorted = url;
                console.log(url);
                if(!callback){
                    Popup().ShortLinkOK(tid, tm, url);
                }else{
                    console.log('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                    eval('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                }
            };
            Mi.erro = function(e){
                console.log('Erro no Migre.me');
                console.log(e.responseText);
                Popup().ShortLinkOK(tid, tm, '');
            };
            Mi.init();
        return shorted;
      },

      Threely:function(LongUrl, tid, tm, other, callback){
        console.log('Shorting URL: '+LongUrl+' With: 3.ly/is.gd');
        var shorted;
        var ap,d;
        switch(other){
            case 'isgd':
                console.log('Threely > is.gd');
                ap = api.isgd;
                d  = {longurl: LongUrl};
                break;
            case 'trim':
                console.log('Threely > tr.im');
                ap = api.trim;
                d  = {url: LongUrl};
                break;
            case 'urli':
               console.log('Threely > URLi');
               ap  = api.urli;
               d   = {format: 'simple', action: 'shorturl', url: LongUrl};
               break;
            case 'miudin':
               console.log('Threely > Miud.in');
               ap  = api.miudin;
               //LongUrl = unescape(LongUrl);
               d   = {url: LongUrl};
               break;
            default:
                console.log('Threely > 3.ly');
                ap = api.threely;
                d  = {api: 'em5893833', u: LongUrl};
        }
        var Ly = new Request(ap, 'get', 'text');
            Ly.dados = d;
            Ly.sucesso = function(url){
                Utils.Short.link = url;
                shorted = url;
                console.log(url);
                if(!callback){
                    Popup().ShortLinkOK(tid, tm, url);
                }else{
                    console.log('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                    eval('Popup().'+callback+'(\''+tid+'\', \''+tm+'\', \''+url+'\')');
                }
            };
            Ly.erro = function(e){
                console.log('Erro no 3.ly/is.gd');
                console.log(e.responseText);
                Popup().ShortLinkOK(tid, tm, '');
            };
            Ly.init();
      },

    },

    Yfrog:{
        vendo:null,
        thumb:function(id){
            Utils.Yfrog.vendo = id;
            return 'http://yfrog.com/'+id+'.th.jpg';
        }
    },

    Twitpic:{
        vendo:null,
        thumb:function(id){
            Utils.Twitpic.vendo = id;
            var size = 'thumb';
            return api.twitpic+size+'/'+id;
        }
    },

    Twitgoo:{
        vendo:null,
        thumb:function(id){
            var pic = new Request(api.twitgoo+id, 'get', 'xml');
                pic.sucesso = function(e){
                    Utils.Twitgoo.vendo = id;
                    var url = $('rsp > thumburl', $(e)).text();
                    try{
                      Popup().Twitgoo(id, url);
                    }catch(e){}
                }
                pic.erro = function(e){
                    console.log(e);
                }
                pic.init();
        }
    },

    Tweetphoto:{

        post:function(){
            var tp = new Request(api.tweetphoto_post, 'post');
                tp.dados = {
                    TPAPIKEY:'f3ccec03ac7803188d3ce28dd4867334',
                    TPMIMETYPE: 'image/jpg',
                };
        },

        thumb:function(url){
            var size = 'medium';
            return api.tweetphoto_view+'?size='+size+'&url='+url;
        }
    }

};

chrome.extension.onRequest.addListener(function(request, sender, sendResponse){
  if(request.novos_tweets) {
    sendResponse({
      'tweets': fec.last(request.tm, request.total, request.max)
    });
  }

  if(request.autorisar){
    OAuth.pin = request.pin;
    chrome.tabs.remove(OAuth.tab);
    OAuth.Access();
  }

  if(request.traduz){
    var re;
      if(typeof(request.texto) == 'object'){
        re = [];
        for(i in request.texto){
            re[i] = Traduz(request.texto[i]);
        }
      }else{
        re = Traduz(request.texto);
      }
      sendResponse({
        'traduzido': re,
        'logado': db.pega('logado')
      });
  }

  if(request.shareVideo){
    console.log('Sharing Video...');
    var titulo = request.videoTitle;
    var id     = request.videoID;
    var URL    = ': http://youtu.be/'+id;
    var txt;

    if(140 < titulo.length +URL.length){
        var tirar = 140 -URL.length -3; // 140 -url -3 (dots)
        txt = [];
        for (var i = 0; i < tirar; i++){
            txt[i] = titulo.charAt(i);
        }
        txt[i] = '...';
        txt = txt.join('') +URL;
    }
    else {
        txt = titulo +URL;
    }

    //console.log('Texto: '+txt);
    Chrowety.update(txt, null, 'home', function(OK){
        sendResponse({
          'enviou': OK
        });
    });
  }

});

function Logout(){
    Chrowety.logout();
}

function OAuthAutoLogin(){
    console.log('OAuthAutoLogin()');
    Logado = true;
    AuthMode = 'OAuth';
    Chrowety.login(true);
}

function AutoLogin(){
    console.log('AutoLogin()');
    Logado = true;
    AuthMode = 'API';
    jQuery.ajaxSetup({'beforeSend': function(xhr){xhr.setRequestHeader("Authorization", "Basic "+db.pega('z_z'))}});
    CheckLimit('Chrowety.Run()');
}

function Login(user,senha,lembra){
  console.log('Login()');
  var login = btoa(user+':'+senha);
  jQuery.ajaxSetup({'beforeSend': function(xhr){xhr.setRequestHeader("Authorization", "Basic "+login)}});
  Chrowety.login(lembra, login);
}

function BrowserAction(){
  chrome.browserAction.setBadgeBackgroundColor({color:[119, 190, 190, 190]});
}

function init() {
  BrowserAction();
  LoadConfig();
  Utils.Sistema.load();
  if(db.pega('logado')){
    if(db.pega('AuthMode') == 'OAuth'){
        OAuth.LoadToken();
        OAuthAutoLogin();
    }else{
        AutoLogin();
    }
  }else{
    OAuth.RequestToken();
  }
}

$(document).ready(init);
</script>
</head>
</html>